线程的等待和通知
Object类中有些方法不可随便调用
wait()、notify()、notifyAll()这三个方法:
1.wait() 使线程主动释放锁,进入等待状态,直到他被其他的线程通过 notify() 和 notifyAll() 唤醒 或者 超过等待时间
2.wait(long) 让当前线程进入等待状态,同时设置时间;直到被通知为止或时间结束
3.notify() 随机通知一个等待线程
4.notifyAll() 通知所有的等待线程
注意:等待和通知方法必须是锁对象,否则会抛出IllegalMonitorStateException
/**
* 通过锁对象将线程等待,经过5秒通知该线程来执行
*/
public class WaitDemo {
public synchronized void waiteTest() throws InterruptedException {
//当前方法等待
System.out.println(Thread.currentThread().getName() + "当前方法等待5s");
this.wait();
}
public synchronized void notifyTest(){
System.out.println("唤醒等待中的方法");
this.notify();
}
public static void main(String[] args) {
WaitDemo waitDemo = new WaitDemo();
Thread thread = new Thread(() -> {
try {
waitDemo.waiteTest();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
try {
Thread.sleep(5000);
waitDemo.notifyTest();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
wait()和sleep()区别
-
调用对象不同
wait() 由锁对象调用
sleep() 由线程调用
-
锁使用不同
执行wait后,自动释放锁
执行sleep后,不会释放锁
-
唤醒机制不同
执行wait后,可以被通知唤醒
执行sleep后,只能等待时间结束后,自动唤醒
生产者消费者模式
例子:假如一个包子铺卖包子,应该是一边生产,一边销售,工作效率最高。如果来了一群顾客,这时候开始一个个生产效率太低,所以顾客还没来就要开始生产,这就需要一个蒸笼,把生产好的包子放在蒸笼里,顾客来了就卖给顾客。
生产者:生产数据的线程或者进程
消费者:使用数据的线程或进程
而蒸笼就相当于一个缓存区
模式实现思路:
1.添加缓冲区,设置上限
2.向缓存区存放数据,满了使生产者进入等待,有空位置则生产
3.消费者从缓冲区使用数据,缓存区没有数据则消费者等待,有数据再通知消费者
解决问题
- 为生产和消费解耦
- 提高并发性能
- 解决忙闲不均
public class BaoziDemo0 {
public static void main