以前其实写过几篇和多线程有关的东西,但感觉都不成体系。随着对并发编程的深入,想系统的整理一下所学所想。一是可以和大家分享,二是可以给自己查漏补缺。先从最基础的常用api聊起。
序言
先说一下我认为学习多线程常用到的api
- java.lang.Object#wait(long):是一个重载方法有多种形式,但最终调用的都是
java.lang.Object#wait(long)
,调用该方法代表着挂起当前线程,释放掉持有的锁,直到有其他线程调用notify或notifyAll方法唤醒该线程,才能再次争抢锁。
注:wait方法必须在synchronized代码块中调用否则会抛出
java.lang.IllegalMonitorStateException
异常
java.lang.Object#notify:随机唤起一个调用wait方法而等待的线程
java.lang.Object#notifyAll:唤起全部应调用wait方法而等待的线程
注:若为特殊情况推荐使用notifyAll方法唤醒等待线程,因为notify随机唤醒的特性可能会导致线程饥饿,导致部分线程一直无法获取到锁
java.lang.Thread#sleep(long):使当前线程休眠指定的毫秒数,不会释放锁
java.lang.Thread#join(long):本质上调用的就是wait方法,使当前线程等待
java.lang.Thread#yield:向调度器表示当前线程愿意让出当前CPU的执行权,但调度器可以忽略这点。
常见的生产者消费者模型
1 | package com.yuehua.concurrent.demo; |
运行以上代码我们会发现有一个问题,那就是生产者必须等待消费者消费完所有数据才能继续生产,消费者也是同理。理想情况下应该是只要队列不满生产者就可以继续生产,只要队列不空消费者就可以继续消费