- 本文采用wait、notify方法实现线程之间的通信
- 假设小明去吃自助餐从餐桌上取食物,服务生小刚专门给提供食物往餐桌上放。这里出现了 小明、小刚、餐桌三者:我们将小明看作消费者线程;小刚看作生产者线程;餐桌看作共享资源,假设餐桌最多放5种食物。以下是代码实现:
模拟餐桌
package thread.produceandcomsume;
//模拟餐桌
public class SelfHelpTable {
//桌子容量
private final int TABLE_CAPACITY = 5;
//桌子上的食物数量
private int foodNums = 0;
//放食物
public synchronized void putFood() {
String name = Thread.currentThread().getName();
//当餐桌满
while(foodNums >= TABLE_CAPACITY) {
try {
System.out.println("桌子上食物的数量"+foodNums+";桌子上的食物满了,"+name +"暂停放食物");
//释放对象锁,将当前线程置于休眠状态
wait();
System.out.println(name +"现在要继续在桌子上放食物了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foodNums ++ ;
System.out.println(name +"放食物成功,桌子上还有"+foodNums);
notify();
}
//拿取食物
public synchronized void bringFood() {
String name = Thread.currentThread().getName();
//当餐桌空了
while(foodNums == 0) {
try {
System.out.println(name +"把桌子上的食物拿光了");
wait();
System.out.println(name +"现在可以继续拿桌子上的东西了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foodNums -- ;
System.out.println(name +"拿取食物成功,桌子上还有"+foodNums);
notify();
}
}
模拟生产者小刚
package thread.produceandcomsume;
//生产者
public class SelfHelpChef implements Runnable {
//共享对象
private SelfHelpTable table;
public SelfHelpChef(SelfHelpTable table) {
super();
this.table = table;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//放食物
table.putFood();
}
}
}
模拟消费者小明
package thread.produceandcomsume;
//消费者
public class SelfHelpConsumer implements Runnable {
//共享对象
private SelfHelpTable table;
public SelfHelpConsumer(SelfHelpTable table) {
super();
this.table = table;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
//这里的sleep比小刚要长一点,为了运行以后刚开始可以拿到食物
Thread.sleep(12);
} catch (InterruptedException e) {
e.printStackTrace();
}
//拿取食物
table.bringFood();
}
}
}
测试
package thread.produceandcomsume;
public class SelfHelpTest {
public static void main(String[] args) {
SelfHelpTable table = new SelfHelpTable();
SelfHelpChef producer = new SelfHelpChef(table);
SelfHelpConsumer consumer = new SelfHelpConsumer(table);
Thread thread2 = new Thread(producer, "服务生小刚");
Thread thread = new Thread(consumer, "消费者小明");
thread2.start();
thread.start();
}
}
需要注意的地方:
- 在使用wait、notify这两个方法的时候,必须拥有对象锁,单独使用的时候会抛出异常
- 方法中的条件判断要用while不能用if