java 多线程系列文章列表, 请查看目录: 《java 多线程学习笔记》
1. 线程通信-Condition
- 当使用synchronized 进行线程同步时, 可以使用Object的wait(), notify(), notifyAll() 方法进行线程通信.
- 但是当使用Lock 对象保证线程同步时, 便不能使用Object 的方法来进行线程通信了, 而是通过Condition 对象进行线程通信
1.1 Condition API
Condition 提供了和Object 通信方法类似的API, 还做了一定的增强.
- awaite():
- 类似于Object的wait()方法, 使当前线程等待. 直达其它线程调用该condition对象的signal()或signalAll()方式时被唤醒.
- condition 还提供了一些增强方法, awaitNanos(long nanosTimeout), awaitUntil(Date), awaituninterruptibly()
- signal(): 唤醒使用该condition对象进入阻塞状态的任意一个线程.
- signalAll(): 唤醒使用该condition 对象进入阻塞状态的所有线程
2. Condition 示例
我们依然借助于签名的示例进行改造, 只是不在使用synchronized 进行加锁, 而是通过Lock 对象进行加锁.
2.1 使用Lock 改造的Product
- Conditon 是通过Lock 对象new出来的.
- 一定要注意释放锁, 放在最外层的finally 代码块儿中
- 一个lock 对象可以创建多个condition 对象, 由哪个Condition对象进入的阻塞状态, 只能被哪个Condition唤醒.
public class Product {
private int number = 1;
// 同步锁
private Lock lock = new ReentrantLock();
// 通信对象
private Condition condition = lock.newCondition();
public void sale(){
// 加锁
lock.lock();
try {
// 如果商品数量小于0 , 则线程等待
while (number <= 0) {
System.out.println("商品剩余为0, 等待补货!");
this.condition.await();
}
System.out.println(Thread.currentThread().getName() + "-售出1件商品, 剩余商品:" + --number);
} catch (Exception e) {
e.printStackTrace();
}finally {
// 一定要记得释放锁
lock.unlock();
}
}
public void purchase() {
// 加锁
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "-进货1件商品, 剩余商品:" + ++number);
// 通知所有的等待线程, 可能会产生虚假唤醒
this.condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
// 一定要记得释放锁
lock.unlock();
}
}
}
2.2 测试用例
public static void main(String[] args) {
Product product = new Product();
// 启动三个线程消费
for (int i = 0; i < 3; i++) {
new Thread("消费者" + i){
@Override
public void run() {
while (true) {
product.sale();
ThreadUtil.sleep(5);
}
}
}.start();
}
// 启动一个线程生产
new Thread("生产者"){
@Override
public void run() {
while (true) {
product.purchase();
ThreadUtil.sleep(10);
}
}
}.start();
ThreadUtil.sleep(10000);
}
2.3 测试输出
消费者1-售出1件商品, 剩余商品:0
商品剩余为0, 等待补货!
生产者-进货1件商品, 剩余商品:1
消费者2-售出1件商品, 剩余商品:0
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
生产者-进货1件商品, 剩余商品:1
消费者0-售出1件商品, 剩余商品:0