假设有这样一种情况,有一个盘子,盘子里只能放一个鸡蛋,A线程专门往盘子里放鸡蛋,如果盘子里有鸡蛋,则一直等到盘子里没鸡蛋,B线程专门从盘子里取鸡蛋,如果盘子里没鸡蛋,则一直等到盘子里有鸡蛋。这里盘子是一个互斥区,每次放鸡蛋是互斥的,每次取鸡蛋也是互斥的,A线程放鸡蛋,如果这时B线程要取鸡蛋,由于A没有释放锁,B线程处于等待状态,进入阻塞队列,放鸡蛋之后,要通知B线程取鸡蛋,B线程进入就绪队列,反过来,B线程取鸡蛋,如果A线程要放鸡蛋,由于B线程没有释放锁,A线程处于等待状态,进入阻塞队列,取鸡蛋之后,要通知A线程放鸡蛋,A线程进入就绪队列。我们希望当盘子里有鸡蛋时,A线程阻塞,B线程就绪,盘子里没鸡蛋时,A线程就绪,B线程阻塞,代码如下:
package com.changchang;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Plate {
private int MAX_INT=10;
LinkedList<Object> eggs = new LinkedList<Object>();
//取鸡蛋
public synchronized void getEggs(){
while(eggs.size()==0){
System.out.println("篮子已经为空");
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object egg = eggs.get(0);
eggs.clear();
try {
Thread.sleep(2200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
notify();
System.out.println("拿到鸡蛋,鸡蛋数量为:"+(eggs.size()));
}
public synchronized void putEgg(Object egg){
//这里注释的地方这样写不满足“如果盘中有鸡蛋,则一直等到盘中没有鸡蛋才往里面放”这个条件
/*while(eggs.size()==MAX_INT){
System.out.println("篮子已经满了");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
while(eggs.size()>0){
System.out.println("不能再放了,这时盘子里面还有鸡蛋");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
eggs.add(egg);
try {
Thread.sleep(1200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("放入鸡蛋,鸡蛋数量为:"+eggs.size());
notify();//
}
static class AddThread implements Runnable{
private Plate plate;
private Object egg = new Object();
public AddThread(Plate plate) {
super();
this.plate = plate;
}
@Override
public void run() {
plate.putEgg(egg);
}
}
static class GetThread implements Runnable{
private Plate plate;
public GetThread(Plate plate) {
super();
this.plate = plate;
}
@Override
public void run() {
plate.getEggs();
}
}
public static void main(String[] args){
Plate plate = new Plate();
for(int i=0;i<100;i++){
new Thread(new AddThread(plate)).start();
new Thread(new GetThread(plate)).start();
}
}
}