这篇文章是对前几篇文章的一个总结,用我们学过的知识点(volatile/CAS/atomicInteger/BlockQueue/线程交互/原子引用)做一个生产者消费者的例子,看下边的代码,我们在main方法中,创建两个线程,一个生产线程,一个消费线程来操作资源类中的阻塞队列,资源类中的生产和消费方法,分别对阻塞队列添加值和移除值,达到一个什么效果呢,生产线程生产一条数据,消费线程就消费掉这条数据,main线程过5秒后,结束此程序。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;public class ProdConsumer_BlockingQueueDemo {
/**
* @param args
*/
public static void main(String[] args) {MyResource myResource = new MyResource(new ArrayBlockingQueue<String>(10));
new Thread(() -> {
System.err.println(Thread.currentThread().getName() + "\t 生产线程启动");
myResource.prod();}, "Prod\t").start();
new Thread(() -> {
System.err.println(Thread.currentThread().getName() + "\t 消费线程启动");
myResource.consumer();
System.err.println();
System.err.println();
}, "Consumer\t").start();try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println();
System.err.println();
System.err.println();System.err.println("5秒钟时间到,大老板main线程叫停,活动结束");
myResource.stop();
}}
class MyResource {
private volatile boolean prodConsumerFlag = true;
private AtomicInteger atomicInteger = new AtomicInteger();
private BlockingQueue<String> blockingQueue = null;public MyResource(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
System.err.println(blockingQueue.getClass().getName());
}public void prod() {
try {
String data = null;while (prodConsumerFlag) {
data = atomicInteger.incrementAndGet() + "";
if (blockingQueue.offer(data, 2L, TimeUnit.SECONDS)) {System.err.println(Thread.currentThread().getName() + "\t 插入队列" + data + "成功");
} else {System.err.println(Thread.currentThread().getName() + "\t 插入队列" + data + "失敗");
}
TimeUnit.SECONDS.sleep(1);
}
System.err.println(Thread.currentThread().getName() + "\t 大老板叫停了,表示prodConsumerFlag=false,生产动作结束");
} catch (Exception e) {
e.printStackTrace();
}}
public void consumer() {
try {
String data = null;while (prodConsumerFlag) {
data = blockingQueue.poll(2L, TimeUnit.SECONDS);
if (null == data || "".equals(data)) {
prodConsumerFlag = false;
System.err.println(Thread.currentThread().getName() + "\t 超过2秒没有取到数据,消息退出");
return;
}
System.err.println(Thread.currentThread().getName() + "\t 消费队列" + data + "成功");
}
} catch (Exception e) {
e.printStackTrace();
}}
public void stop() {
prodConsumerFlag = false;
}}
执行结果
java.util.concurrent.ArrayBlockingQueue
Prod 生产线程启动
Consumer 消费线程启动
Prod 插入队列1成功
Consumer 消费队列1成功
Prod 插入队列2成功
Consumer 消费队列2成功
Prod 插入队列3成功
Consumer 消费队列3成功
Prod 插入队列4成功
Consumer 消费队列4成功
Prod 插入队列5成功
Consumer 消费队列5成功5秒钟时间到,大老板main线程叫停,活动结束
Prod 大老板叫停了,表示prodConsumerFlag=false,生产动作结束
Consumer 超过2秒没有取到数据,消息退出