在现实生活中,线程往往需要互相协作才可以更好的运行,比如,消费者--生产者模型,消费者往仓库中取商品时,仓库中得有商品才能实现,否则消费者进入等待状态,而生产者得不到仓库的占用权,无法将商品放入仓库,此时消费者就会进入无限等待状态。同理,生产者往仓库放入商品,仓库得有空间去存放商品,当仓库没有空间时,生产者会进入等待状态,而消费者得不到仓库的占用权,无法取出商品,此时生产者就会进入无线等待状态。
为了解决这个问题,Java中采用了wait(),notify()这两种线程协作方式,前者为等待,后者为通知,当消费者取出商品时,生产者会通知消费者放入商品,而生产者在仓库没有空间时,会进入等待状态,通知消费者取出商品。
For Example:
package Test2;
import java.util.ArrayList;
public class Main {
public static ArrayList<Integer> al = new ArrayList<Integer>();
public static void main(String[] args) {
Consume cs = new Consume(al);
Produce pd = new Produce(al);
cs.start();
pd.start();
}
}
package Test2;
import java.util.ArrayList;
public class Consume extends Thread{
ArrayList<Integer> al;
public Consume( ArrayList<Integer> al)
{
this.al = al;
}
public void run() {
while(true)
{
synchronized (al) {
while(al.size() == 0)
{
try {
System.out.println("仓库为空,进入等待状态");
al.wait();
} catch (InterruptedException e) {
e.printStackTrace();
al.notify();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al.remove(al.size()-1);
al.notify();
System.out.println("已取出商品");
}
}
}
}
package Test2;
import java.util.ArrayList;
public class Produce extends Thread{
ArrayList<Integer> al;
int count = 1;
public Produce(ArrayList<Integer> al)
{
this.al = al;
}
public void run() {
while(true)
{
synchronized (al) {
if(al.size() == 2)
{
try {
System.out.println("仓库已满,进入等待状态");
al.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
al.notify();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al.add(count);
al.notify();
System.out.println("已经生产"+count+"商品");
count ++;
}
}
}
}
结果为:
仓库为空,进入等待状态
已经生产1商品
已取出商品
已经生产2商品
已取出商品
已经生产3商品
已经生产4商品
已取出商品
已取出商品
仓库为空,进入等待状态
已经生产5商品
已经生产6商品
仓库已满,进入等待状态
已取出商品
已经生产7商品
仓库已满,进入等待状态
已取出商品
已经生产8商品
仓库已满,进入等待状态
已取出商品