转载请注明出处:http://blog.csdn.net/sunyujia/
论坛上的网友提出的问题,每生产3个只能消费2个,感觉不是很难于是动手操之,为了省事
在原来的http://blog.csdn.net/sunyujia/archive/2008/05/02/2362015.aspx 基础上修改的。
唯一的难点在于生产3个的线程不是同一线程。消费2个的线程不是同一线程。就是说不能是一个线程连续生产3个,一个线程连续消费2个,如果是一个线程连续生产的话,程序就没意思了。
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- /**
- * 有趣的生产者消费者问题
- * 每生成3个消费2个
- * @author: sunyujia
- * @blog: http://blog.csdn.net/sunyujia/
- * @mail: sunyujia@sunyujia@yahoo.cn
- */
- public class ExecutorServiceTest {
- private static int produceCount = 0;
- private static int consumeCount = 0;
- private static Object produceLock = new Object();
- private static Object consumeLock = new Object();
- public static void main(String[] args) {
- final List tasks = new ArrayList();
- System.out.println("MyBlog: http://blog.csdn.net/"+"sunyujia/");
- final ExecutorService exec = Executors.newCachedThreadPool();
- for (int i = 0; i < 10; i++) {//10个生产者
- exec.execute(new Runnable() {
- public void run() {
- while (!Thread.interrupted()) {
- try {
- synchronized (consumeLock) {
- if (produceCount >= 3)
- consumeLock.wait();
- }
- synchronized (produceLock) {
- if (produceCount < 3) {
- tasks.add(new Object());// 生产
- System.out.println(Thread.currentThread().getName()+"生产任务 还剩:" + tasks.size());
- produceCount++;
- if (produceCount >= 3) {
- consumeCount = 2;// 提示只能消费2个
- System.out.println("生产者友情提示现在库存"
- + tasks.size());
- produceLock.notifyAll();
- }
- Thread.yield();
- }
- }
- Thread.sleep(600);// 让程序执行慢点以便观察
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- });
- }
- for (int i = 0; i < 20; i++) {//20个消费者
- exec.execute(new Runnable() {
- public void run() {
- while (!Thread.interrupted()) {
- try {
- synchronized (produceLock) {
- if (consumeCount <= 0)
- produceLock.wait();
- }
- synchronized (consumeLock) {
- if (consumeCount > 0) {
- tasks.remove(0);// 消费
- System.out.println(Thread.currentThread().getName()+"处理任务 还剩:"
- + tasks.size());
- consumeCount--;
- if (consumeCount <= 0) {
- produceCount = 0;// 要求再生成3个
- System.out.println("消费者友情提示现在库存"
- + tasks.size());
- consumeLock.notifyAll();
- }
- }
- }
- Thread.sleep(600);// 让程序执行慢点以便观察
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- });
- }
- exec.shutdown();
- }
- }
执行结果如下:
pool-1-thread-1生产任务 还剩:1
pool-1-thread-2生产任务 还剩:2
pool-1-thread-4生产任务 还剩:3
生产者友情提示现在库存3
pool-1-thread-11处理任务 还剩:2
pool-1-thread-12处理任务 还剩:1
消费者友情提示现在库存1
pool-1-thread-5生产任务 还剩:2
pool-1-thread-6生产任务 还剩:3
pool-1-thread-7生产任务 还剩:4
生产者友情提示现在库存4
pool-1-thread-14处理任务 还剩:3
pool-1-thread-16处理任务 还剩:2
消费者友情提示现在库存2
pool-1-thread-3生产任务 还剩:3
pool-1-thread-2生产任务 还剩:4
pool-1-thread-4生产任务 还剩:5
生产者友情提示现在库存5