线程同步问题:共享内存区域被多个线程访问,至少有一个线程是写操作
协调多个线程的并发执行的过程称为同步(Synchronization) 协调多个线程对共享内存区域的访问 确保按照某种正确顺序访问共享内存区域 基本方法:使用 synchronized关键字 线程互斥:synchronized 修饰类的方法 或者代码块 ,保证同一时刻最多只有一个线程能够执行这个类的对象被 synchronized 修饰的方法 或者 代码块。 三个线程同时买票问题:package thread;import static java.lang.Thread.sleep;public class BuyTicket { public static void main(String[] args) { //创建一个Runnable接口对象 Ticket ticket = new Ticket(); //new三个线程操作同一个对象ticket new Thread(ticket, "Yoimiya").start(); new Thread(ticket, "Fischl").start(); new Thread(ticket, "Xiao").start(); }}class Ticket implements Runnable { int tickets = 10; //票数 boolean flag = true; //外部停止方式 @Override public void run() { //买票 while(flag){ try { sleep(200); //模拟延时(,放大问题) } catch (InterruptedException e) { e.printStackTrace(); } buyTicket(); } } //synchronized 同步方法, 锁的是this public synchronized void buyTicket(){ if(tickets <= 0){ flag = false; //外部停止 }else{ //获取当前Thread对象名 System.out.println(Thread.currentThread().getName() + "买了第" + tickets-- + "张票"); } }}
银行账户存取款问题:(存钱方法和取钱方法都写在Account类里,使用synchronized实现互斥)
package thread;import static java.lang.Thread.MAX_PRIORITY;import static java.lang.Thread.sleep;public class BankAccount { public static void main(String[] args) { Account account = new Account(1000,"Yoimiya");//创建银行账户对象 SaveMoney saveMoney = new SaveMoney(account, 100);//创建存钱线程 DrawMoney drawMoney = new DrawMoney(account,800);//创建取钱线程 DrawMoney drawMoney01 = new DrawMoney(account,500); Thread thread = new Thread(saveMoney, "Yoimiya"); thread.setPriority(MAX_PRIORITY); //线程设置优先级(1-10)(MAX_PRIORITY == 10) thread.start(); //开启线程 new Thread(drawMoney, "Yoimiya").start(); new Thread(drawMoney01, "Xiao").start(); }}class Account{ private double money; //账户余额 private String name; //账户名(此段代码无用) public Account(double money, String name) {//有参构造(传递参数) this.money = money; this.name = name; } //存钱方法,使用synchronized同步 public synchronized double saveMoney(double saveMoney){ money = money + saveMoney; System.out.println(Thread.currentThread().getName() + "存了" + saveMoney + ",现在余额为" + money); return money; } //取钱方法,使用synchronized同步 public synchronized double drawMoney(double drawMoney){ if(money >= drawMoney){ money = money - drawMoney; System.out.println(Thread.currentThread().getName() + "取了" + drawMoney + "余额为" + money); } else{ System.out.println(Thread.currentThread().getName() + "要取" + drawMoney + "余额为" + money + "不足"); } return money; }}//创建存钱线程class SaveMoney implements Runnable{ private Account account; private double saveMoney; public SaveMoney(Account account, double saveMoney) { this.account = account; this.saveMoney = saveMoney; } @Override public void run() { try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } account.saveMoney(saveMoney); }}//创建取钱线程class DrawMoney implements Runnable{ private Account account; private double drawMoney; public DrawMoney(Account account, double drawMoney) { this.account = account; this.drawMoney = drawMoney; } @Override public void run() { try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.drawMoney(drawMoney); }}