1、线程通信模型
- 线程间通信的模型有两种:共享内存和消息传递
2、线程通信方式一:Object.wait() 和 notify()
wait/notify注意事项
- wait/notify必须在同步代码块或者同步函数中使用
- wait/notify必须由同一个锁对象调用
- wait/notify方法属于Object的方法,所以锁对象可以是任意对象
notify之后不是表示线程立即恢复执行,因为当初中断的地方是在同步代码块中,而此刻它已经不再持有锁,它需要再去和其他线程抢锁
生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。
public class Main {
public static void main(String[] args) throws InterruptedException {
Storage storage = new Storage();
Thread p1 = new Thread(new Producer(storage));
Thread p2 = new Thread(new Producer(storage));
Thread p3 = new Thread(new Producer(storage));
Thread c1 = new Thread(new Consumer(storage));
Thread c2 = new Thread(new Consumer(storage));
Thread c3 = new Thread(new Consumer(storage));
c1.start();
c2.start();
c3.start();
p1.start();
p2.start();
p3.start();
}
/**
* 生产者
*/
public static class Producer extends Thread {
private Storage storage;
public Producer(){}
public Producer(Storage storage){
this.storage = storage;
}
@Override
public void run(){
while(true){
try{
Thread.sleep(1000);
storage.produce();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
/**
* 消费者
*/
public static class Consumer extends Thread {
private Storage storage;
public Consumer(){}
public Consumer(Storage storage){
this.storage = storage;
}
@Override
public void run(){
while(true){
try{
Thread.sleep(3000);
storage.consume();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
/**
* 仓库类
*/
public static class Storage extends Thread {
// 仓库容量
private final int MAX_SIZE = 10;
// 仓库存储的载体
private LinkedList<Object> list = new LinkedList<>();
public void produce() {
synchronized (list) {
while (list.size() + 1 > MAX_SIZE) {
System.out.println("【生产者" + Thread.currentThread().getName()
+ "】仓库已满");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(new Object());
System.out.println("【生产者" + Thread.currentThread().getName()
+ "】生产一个产品,现库存" + list.size());
list.notifyAll();
}
}
public void consume() {
synchronized (list) {
while (list.size() == 0) {
System.out.println("【消费者" + Thread.currentThread().getName()
+ "】仓库为空");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove();
System.out.println("【消费者" + Thread.currentThread().getName()
+ "】消费一个产品,现库存" + list.size());
list.notifyAll();
}
}
}
}