线程通信
线程间通信的方法:
经典模型:生产者消费者模式
1.管程法:
package threadStudy; public class ThreadCommunicate { public static void main(String[] args) { Buffer buffer = new Buffer(); new Producer(buffer).start(); new Consumer(buffer).start(); } } class Producer extends Thread { Buffer buffer; public Producer(Buffer buffer) { this.buffer = buffer; } @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("生产的第" + i + "杯奶茶" ); buffer.add(new MilkTea(i)); } } } class Consumer extends Thread { Buffer buffer; public Consumer(Buffer buffer) { this.buffer = buffer; } @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("消费的第" + i + "杯奶茶" ); buffer.pop(); } } } //缓冲区 class Buffer { MilkTea[] milkTea = new MilkTea[10]; private int count = 0; public synchronized void add(MilkTea m) { //缓冲区满了 停止生产 if(count==milkTea.length) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } milkTea[count] = m; count++; this.notifyAll(); } public synchronized MilkTea pop() { //缓冲区无东西 停止消费 if(count==0) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } count--; MilkTea temp = milkTea[count]; this.notifyAll(); return temp; } } class MilkTea { int id; public MilkTea(int id) { this.id = id; } }
输出:
生产的第0杯奶茶
消费的第0杯奶茶
消费的第1杯奶茶
生产的第1杯奶茶
生产的第2杯奶茶
消费的第2杯奶茶
生产的第3杯奶茶
消费的第3杯奶茶
消费的第4杯奶茶
生产的第4杯奶茶
生产的第5杯奶茶
生产的第6杯奶茶
生产的第7杯奶茶
生产的第8杯奶茶
生产的第9杯奶茶
生产的第10杯奶茶
生产的第11杯奶茶
生产的第12杯奶茶
生产的第13杯奶茶
生产的第14杯奶茶
生产的第15杯奶茶
消费的第5杯奶茶
消费的第6杯奶茶
生产的第16杯奶茶
消费的第7杯奶茶
消费的第8杯奶茶
生产的第17杯奶茶
消费的第9杯奶茶
生产的第18杯奶茶
消费的第10杯奶茶
生产的第19杯奶茶
消费的第11杯奶茶
消费的第12杯奶茶
消费的第13杯奶茶
消费的第14杯奶茶
消费的第15杯奶茶
消费的第16杯奶茶
消费的第17杯奶茶
消费的第18杯奶茶
消费的第19杯奶茶
2.信号灯法
package threadStudy; public class ThreadCommunicate2 { public static void main(String[] args) { Song song = new Song(); new Actor(song).start(); new Audience(song).start(); } } class Actor extends Thread{ Song song; public Actor(Song song) { this.song = song; } @Override public void run() { for (int i = 0; i < 10; i++) { if(i%2==0) { song.sing("发如雪"); } else { song.sing("青花瓷"); } } } } class Audience extends Thread{ Song song; public Audience(Song song) { this.song = song; } @Override public void run() { for (int i = 0; i < 10; i++) { song.listen(); } } } class Song{ private String name; //true 表示演员已经唱好了 false表示还未唱好 即还不可以挺 private boolean flag = false; public synchronized void sing(String name) { if(flag) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.name = name; System.out.println("周杰伦唱了:"+name); this.notifyAll(); flag = !flag; } public synchronized void listen() { if(!flag) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("我听了:"+this.name); this.notifyAll(); flag = !flag; } }
输出:
周杰伦唱了:发如雪
我听了:发如雪
周杰伦唱了:青花瓷
我听了:青花瓷
周杰伦唱了:发如雪
我听了:发如雪
周杰伦唱了:青花瓷
我听了:青花瓷
周杰伦唱了:发如雪
我听了:发如雪
周杰伦唱了:青花瓷
我听了:青花瓷
周杰伦唱了:发如雪
我听了:发如雪
周杰伦唱了:青花瓷
我听了:青花瓷
周杰伦唱了:发如雪
我听了:发如雪
周杰伦唱了:青花瓷
我听了:青花瓷