在现实应用中,很多时候都需要让多个线程按照一定的次序来访问共享资源,例如,经典的生产者和消费者问题。
仓库中没有产品时,消费者要等待生产者生产产品;当仓库满时,生产者要等待消费者消费产品;在仓库中有产品但
未满时,消费者可以消费产品,生产者可以生产产品。可以采用循环检测的方法来实现,但是可以利用提供的wait(),
notify(),notifyAll()来更好的处理。
共享资源:
/**
* 文件:Resoures.java
* 描述:TODO
* 作者:luckystar2008
* 日期:2012-1-10
*/
package thread.product.customer.multiple;
/**
* @author luckystar2008
*
*/
public class Resoures {
private char[] cArr = new char[5]; //模拟仓库,存放5个字符
private int index = 0; //信号量,初始值为0
public synchronized void push(char c) {
if (index == cArr.length) { //仓库已满
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
cArr[index] = c;
index++;
notify();
}
public synchronized char pop() {
if (index == 0) { //仓库是空的,等待生产者生产产品
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
index--;
notify();
return cArr[index];
}
}
生产者:
/**
* 文件:Productor.java
* 描述:模拟生产者
* 作者:luckystar2008
* 日期:2012-1-10
*/
package thread.product.customer.multiple;
/**
* @author luckystar2008
*
*/
public class Productor extends Thread{
private Resoures r ;
public Productor(Resoures r) {
this.r = r;
}
public void run() {
for (int i=0;i<5;i++) {
char c = (char)(Math.random()*26+'A');
System.out.println("Push element " + c);
r.push(c);
try {
Thread.sleep((long)Math.random()*3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
模拟消费者:
/**
* 文件:Consumer.java
* 描述:模拟消费者
* 作者:luckystar2008
* 日期:2012-1-10
*/
package thread.product.customer.multiple;
/**
* @author luckystar2008
*
*/
public class Consumer extends Thread{
private Resoures r;
public Consumer(Resoures r) {
this.r =r ;
}
public void run() {
for (int i=0;i<5;i++) {
char c = r.pop();
System.out.println("Pop element " + c);
try {
Thread.sleep((long)Math.random()*3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
测试:
/**
* 文件:Test.java
* 描述:测试
* 作者:luckystar2008
* 日期:2012-1-10
*/
package thread.product.customer.multiple;
/**
* @author luckystar2008
* 生产者和消费者可以同时生产或消费多个产品。
*/
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Resoures r = new Resoures();
Productor p = new Productor(r);
Consumer c = new Consumer(r);
c.start();
p.start();
}
}