java 多线程系列文章列表, 请查看目录: 《java 多线程学习笔记》
1. 线程通信的传统方式
传统的线程通信方式指的是借助于, Object 基类中的wait(), notify(), notifyAll()方法. 这三个方法必须由同步监视器对象进行调用, 影响的也只是同一同步监视器的相关线程.
1.1 同步监视器
同步监视器, 也就是指监视的资源. 对于synchronized 同步方式, 有两种情况:
- synchronized 修饰的同步方法, 同步监视器为该对象实例 this
- synchronized 修饰的同步代码块儿, 同步监视器为括号里的对象, 因此必须调用该括号内的对象的wait(), notify(), notifyAll() 方法
// 同步方法, 默认同步监视器为this对象, 所以直接调用this 对象的wait(), notify(), notifyAll() 方法
synchronized public void doWait(){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 同步代码块儿, 同步监视器为字符串常量"hello", 所以需要使用字符串的wait()方法.
// 需要注意的是, 由于java 常量位于常量池中, 所以相同字符串为同一对象, 所以可不指定变量名称.
public void doWait(){
synchronized ("hello"){
try {
"hello".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1.2 API 说明
- wait(): 阻塞API, 使线程由运行状态转为阻塞状态, 等待被唤醒.
- notify(): 唤醒当前同步监视器的任一一个等待线程, 使线程由阻塞状态转为就绪状态, 等待cpu 资源调度
- notifyAll(): 唤醒当前同步监视器的所有等待线程.
2. 线程通信测试
笔者来模拟一个生产者消费者模型, 当
2.1 Product
- 笔者采用同步方法方式, 因此默认同步监视器为 this
- 当产品数量小于0时, 销售等待, 当产品大于0 时, 可以销售.
public class Product {
private int number = 1;
synchronized public void sale(){
try {
// 如果商品数量小于0 , 则线程等待
while (number <= 0) {
System.out.println("商品剩余为0, 等待补货!");
this.wait();
}
System.out.println(Thread.currentThread().getName() + "-售出1件商品, 剩余商品:" + --number);
} catch (Exception e) {
e.printStackTrace();
}
}
synchronized public void purchase() {
try {
System.out.println(Thread.currentThread().getName() + "-进货1件商品, 剩余商品:" + ++number);
// 通知所有的等待线程, 可能会产生虚假唤醒
this.notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2 测试类
笔者启动3个消费者线程, 1个生产者线程. 这样便有3个消费者线程在等待.
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 测试输出
从测试可看出, 当商品剩余数量为0时, 消费者线程进行等待.
消费者0-售出1件商品, 剩余商品:0
生产者-进货1件商品, 剩余商品:1
消费者2-售出1件商品, 剩余商品:0
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
生产者-进货1件商品, 剩余商品:1
消费者1-售出1件商品, 剩余商品:0
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
商品剩余为0, 等待补货!
生产者-进货1件商品, 剩余商品:1
消费者0-售出1件商品, 剩余商品:0