1 package CoTest; 2 3 /** 4 * 信号灯 5 * 借助标志位 6 * @author yuche 7 * 8 */ 9 10 public class CoTest2 {11 public static void main(String[] args) {12 Bread1 bread=new Bread1();13 new Producer1(bread).start();14 new Consumer1(bread).start();15 16 }17 18 }19 20 class Consumer1 extends Thread{21 Bread1 bread;22 23 public Consumer1(Bread1 bread) {24 super();25 this.bread = bread;26 }27 28 @Override29 public void run() {30 for(int i=1;i<100;++i) {31 consume(); 32 }33 }34 35 public synchronized void consume(){36 if(bread.flag) {37 try {38 this.wait();39 } catch (InterruptedException e) {40 e.printStackTrace();41 }42 }43 System.out.println("消费");44 bread.flag=!bread.flag;45 this.notifyAll();46 }47 48 }49 50 class Producer1 extends Thread{51 Bread1 bread;52 53 public Producer1(Bread1 bread) {54 super();55 this.bread = bread;56 }57 58 @Override59 public void run() {60 for(int i=1;i<100;++i) {61 produce();62 }63 }64 65 public synchronized void produce(){66 if(!bread.flag) {67 try {68 this.wait();69 } catch (InterruptedException e) {70 e.printStackTrace();71 }72 }73 System.out.println("生产");74 bread.flag=!bread.flag;75 this.notifyAll();76 }77 }78 79 //资源80 class Bread1{81 //为T表示面包在生产,为F表示可以消费了82 boolean flag;83 public Bread1() {84 flag=true;85 }86 }
运行后,出现一次生产,出现一次消费后就结束了,无法相互唤醒。查找资料后发现我加的锁在2个线程中,没有交点不会相互唤醒。因此把同步方法放入Bread类中可解决,修改后的代码如下
1 package CoTest; 2 3 /** 4 * 信号灯 5 * 借助标志位 6 * @author yuche 7 * 8 */ 9 10 public class CoTest2 {11 public static void main(String[] args) {12 Bread1 bread=new Bread1();13 new Producer1(bread).start();14 new Consumer1(bread).start();15 }16 }17 18 class Consumer1 extends Thread{19 Bread1 bread;20 21 public Consumer1(Bread1 bread) {22 super();23 this.bread = bread;24 }25 26 @Override27 public void run() {28 for(int i=1;i<100;++i) {29 bread.consume(); 30 }31 } 32 }33 34 class Producer1 extends Thread{35 Bread1 bread;36 37 public Producer1(Bread1 bread) {38 super();39 this.bread = bread;40 }41 42 @Override43 public void run() {44 for(int i=1;i<100;++i) {45 bread.produce();46 }47 }48 }49 50 //资源51 //同步方法要放在资源里,没有交点不会相互唤醒52 class Bread1{53 //为T表示面包在生产,为F表示可以消费了54 boolean flag;55 public Bread1() {56 flag=true;57 }58 59 public synchronized void produce(){60 if(!this.flag) {61 try {62 this.wait();63 } catch (InterruptedException e) {64 e.printStackTrace();65 }66 }67 System.out.println("生产");68 this.flag=!this.flag;69 this.notifyAll();70 }71 72 public synchronized void consume(){73 if(this.flag) {74 try {75 this.wait();76 } catch (InterruptedException e) {77 e.printStackTrace();78 }79 }80 System.out.println("消费");81 this.flag=!this.flag;82 this.notifyAll();83 }84 }