废话不多说直接上代码:
package 线程;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class TestBlockingQueue {
static BlockingQueue <Mantu> queue=new LinkedBlockingQueue <Mantu>(6);
public static void main(String[] args) throws InterruptedException {
Producer3 t1 = new Producer3();
Consumer3 t2 = new Consumer3();
t1.start();
t2.start();
Thread.sleep(1000);
t2.interrupt();
}
}
class Mantu{
int id;
public Mantu(int id) {
this.id=id;
}
@Override
public String toString() {
return ""+id;
}
}
class Producer3 extends Thread{
@Override
public void run() {
int i=0;
while(i<10){
Mantu e = new Mantu(i);
try {
System.out.println("生产馒头"+i);
TestBlockingQueue.queue.put(e);
} catch (InterruptedException e1) {
System.out.println("馒头太多生产被停止了");
return;
}
i++;
}
}
}
class Consumer3 extends Thread{
@Override
public void run() {
while(true){
try {
System.out.println("吃馒头"+TestBlockingQueue.queue.take());
} catch (InterruptedException e1) {
System.out.println("馒头不够吃被停止了");
return;
}
}
}
}
由于阻塞队列LinkedBlockingQueue,FIFO,使用它的put(),take()会判断当前队列是有值,即等待生产再消费,即便是两个线程并行执行,很简单方便的解决了,生产者消费者问题,,但是在这里需要注意的是在两个run()方法中,打印当前生产或消费的馒头值时候,最好把put()和take();方法放在相应的打印语句中一起执行,否则会发生先消费后生产的后果。 因为打印语句和方法的执行时两段代码,由于双线程同时执行,无法保证执行的相应代码块的顺序性!!
由于最后互相等待会造成死锁,所以在主线程睡眠1秒后打断消费者,让它别等了,抛异常后return结束消费线程,最后整个main方法调用结束。