Concurrent - Producer & Consumer

原创转载请注明出处:http://agilestyle.iteye.com/blog/2343193

 

生产者与消费者模式

使用wait/notify实现生产者与消费者模式

package org.fool.test;

import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedDeque;

public class WaitNotifyTest {
	public static void main(String[] args) {
		Queue<Integer> queue = new ConcurrentLinkedDeque<>();

		Thread p = new Thread(new Producer(queue));
		Thread c1 = new Thread(new Consumer(queue));
		Thread c2 = new Thread(new Consumer(queue));

		p.setName("Producer");
		c1.setName("Consumer-1");
		c2.setName("Consumer-2");

		p.start();
		c1.start();
		c2.start();
	}

	public static class Producer implements Runnable {
		private Queue<Integer> queue;

		public Producer(Queue<Integer> queue) {
			this.queue = queue;
		}

		@Override
		public void run() {
			while (true) {
				synchronized (queue) {

					try {
						while (queue.size() == 10) {
							queue.wait();
						}

						Thread.sleep(1000);

						int n = new Random().nextInt(10000);
						queue.add(n);

						System.out.println(Thread.currentThread().getName() + " produce: " + n);

						queue.notifyAll();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}

	}

	public static class Consumer implements Runnable {
		private Queue<Integer> queue;

		public Consumer(Queue<Integer> queue) {
			this.queue = queue;
		}

		@Override
		public void run() {
			while (true) {
				try {
					synchronized (queue) {
						while (queue.isEmpty()) {
							queue.wait();
						}

						Thread.sleep(1000);

						int n = queue.remove();

						System.out.println(Thread.currentThread().getName() + " consume: " + n);

						queue.notifyAll();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Console Output


 

使用BlockingQueue实现生产者与消费者模式

package org.fool.java.concurrent.producerconsumer;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {

    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100);

        Producer producer = new Producer(queue);
        Consumer consumer1 = new Consumer(queue);
        Consumer consumer2 = new Consumer(queue);

        Thread p = new Thread(producer);
        p.setName("Producer");

        Thread c1 = new Thread(consumer1);
        c1.setName("Consumer1");
        Thread c2 = new Thread(consumer2);
        c2.setName("Consumer2");

        p.start();
        c1.start();
        c2.start();
    }

    public static class Producer implements Runnable {
        private final BlockingQueue<Integer> queue;

        public Producer(BlockingQueue<Integer> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Thread.sleep(1000);
                    queue.put(produce());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private int produce() {
            int n = new Random().nextInt(10000);
            System.out.println(Thread.currentThread().getName() + " produce: " + n);

            return n;
        }
    }

    public static class Consumer implements Runnable {
        private final BlockingQueue<Integer> queue;

        public Consumer(BlockingQueue<Integer> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Thread.sleep(2000);
                    consume(queue.take());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void consume(Integer n) {
            System.out.println(Thread.currentThread().getName() + " consume: " + n);
        }
    }
}

Console Output

 

使用Semaphore实现生产者与消费者模式,并且限制生产者与消费者的数量

Service.java

package org.fool.java.concurrent.semaphore.producerconsumer;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Service {
    private volatile Semaphore setSemaphore = new Semaphore(10);
    private volatile Semaphore getSemaphore = new Semaphore(30);
    private volatile ReentrantLock lock = new ReentrantLock();
    private volatile Condition setCondition = lock.newCondition();
    private volatile Condition getCondition = lock.newCondition();
    private Object[] producePosition = new Object[4];

    private boolean isEmpty() {
        boolean isEmpty = true;

        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] != null) {
                isEmpty = false;
                break;
            }
        }

        return isEmpty;
    }

    private boolean isFull() {
        boolean isFull = true;

        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] == null) {
                isFull = false;
                break;
            }
        }

        return isFull;
    }

    public void set() {
        try {
            setSemaphore.acquire();

            lock.lock();

            while (isFull()) {
                setCondition.await();
            }

            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] == null) {
                    producePosition[i] = " Data ";
                    System.out.println(Thread.currentThread().getName() + " produced " + producePosition[i]);

                    break;
                }
            }

            getCondition.signalAll();

            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            setSemaphore.release();
        }
    }

    public void get() {
        try {
            getSemaphore.acquire();

            lock.lock();

            while (isEmpty()) {
                getCondition.await();
            }

            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] != null) {
                    System.out.println(Thread.currentThread().getName() + " consumed " + producePosition[i]);
                }
                producePosition[i] = null;
                break;
            }

            setCondition.signalAll();

            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            getSemaphore.release();
        }
    }
}

Note:

这里设置了10个Producer,30个Consumer

 

ProducerThread.java

package org.fool.java.concurrent.semaphore.producerconsumer;

public class ProducerThread implements Runnable {
    private Service service;

    public ProducerThread(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        service.set();
    }
}

ConsumerThread.java

package org.fool.java.concurrent.semaphore.producerconsumer;

public class ConsumerThread implements Runnable {
    private Service service;

    public ConsumerThread(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        service.get();
    }
}

Test.java

package org.fool.java.concurrent.semaphore.producerconsumer;

import java.util.Random;

public class Test {
    public static void main(String[] args) {
        Service service = new Service();

        for (int i = 0; i < 50; i++) {
            new Thread(new ProducerThread(service)).start();
            new Thread(new ProducerThread(service)).start();
            new Thread(new ProducerThread(service)).start();
            new Thread(new ConsumerThread(service)).start();
            new Thread(new ConsumerThread(service)).start();
            new Thread(new ConsumerThread(service)).start();
        }
    }
}

 

Run 

"C:\Program Files\Java\jdk1.8.0_77\bin\java" -Didea.launcher.port=7535 "-Didea.launcher.bin.path=F:\Program Files\JetBrains\IntelliJ IDEA\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_77\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\rt.jar;E:\workspace-idea\HelloJava\out\production\HelloJava;F:\Program Files\JetBrains\IntelliJ IDEA\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain org.fool.java.concurrent.semaphore.producerconsumer.Test
Thread-0 produced  Data 
Thread-1 produced  Data 
Thread-2 produced  Data 
Thread-3 consumed  Data 
Thread-6 produced  Data 
Thread-7 produced  Data 
Thread-9 consumed  Data 
Thread-8 produced  Data 
Thread-10 consumed  Data 
Thread-12 produced  Data 
Thread-15 consumed  Data 
Thread-13 produced  Data 
Thread-16 consumed  Data 
Thread-14 produced  Data 
Thread-17 consumed  Data 
Thread-18 produced  Data 
Thread-21 consumed  Data 
Thread-19 produced  Data 
Thread-22 consumed  Data 
Thread-20 produced  Data 
Thread-23 consumed  Data 
Thread-24 produced  Data 
Thread-27 consumed  Data 
Thread-25 produced  Data 
Thread-28 consumed  Data 
Thread-26 produced  Data 
Thread-29 consumed  Data 
Thread-30 produced  Data 
Thread-33 consumed  Data 
Thread-31 produced  Data 
Thread-34 consumed  Data 
Thread-32 produced  Data 
Thread-35 consumed  Data 
Thread-36 produced  Data 
Thread-39 consumed  Data 
Thread-37 produced  Data 
Thread-40 consumed  Data 
Thread-38 produced  Data 
Thread-41 consumed  Data 
Thread-42 produced  Data 
Thread-45 consumed  Data 
Thread-43 produced  Data 
Thread-46 consumed  Data 
Thread-44 produced  Data 
Thread-47 consumed  Data 
Thread-48 produced  Data 
Thread-51 consumed  Data 
Thread-49 produced  Data 
Thread-52 consumed  Data 
Thread-55 produced  Data 
Thread-53 consumed  Data 
Thread-50 produced  Data 
Thread-57 consumed  Data 
Thread-54 produced  Data 
Thread-58 consumed  Data 
Thread-56 produced  Data 
Thread-59 consumed  Data 
Thread-60 produced  Data 
Thread-63 consumed  Data 
Thread-61 produced  Data 
Thread-64 consumed  Data 
Thread-62 produced  Data 
Thread-65 consumed  Data 
Thread-66 produced  Data 
Thread-69 consumed  Data 
Thread-67 produced  Data 
Thread-70 consumed  Data 
Thread-68 produced  Data 
Thread-71 consumed  Data 
Thread-72 produced  Data 
Thread-75 consumed  Data 
Thread-73 produced  Data 
Thread-76 consumed  Data 
Thread-74 produced  Data 
Thread-77 consumed  Data 
Thread-78 produced  Data 
Thread-81 consumed  Data 
Thread-79 produced  Data 
Thread-82 consumed  Data 
Thread-80 produced  Data 
Thread-83 consumed  Data 
Thread-84 produced  Data 
Thread-87 consumed  Data 
Thread-85 produced  Data 
Thread-88 consumed  Data 
Thread-86 produced  Data 
Thread-89 consumed  Data 
Thread-90 produced  Data 
Thread-93 consumed  Data 
Thread-91 produced  Data 
Thread-95 consumed  Data 
Thread-92 produced  Data 
Thread-99 consumed  Data 
Thread-96 produced  Data 
Thread-100 consumed  Data 
Thread-97 produced  Data 
Thread-101 consumed  Data 
Thread-98 produced  Data 
Thread-105 consumed  Data 
Thread-102 produced  Data 
Thread-106 consumed  Data 
Thread-104 produced  Data 
Thread-107 consumed  Data 
Thread-103 produced  Data 
Thread-111 consumed  Data 
Thread-108 produced  Data 
Thread-112 consumed  Data 
Thread-109 produced  Data 
Thread-113 consumed  Data 
Thread-110 produced  Data 
Thread-117 consumed  Data 
Thread-114 produced  Data 
Thread-118 consumed  Data 
Thread-115 produced  Data 
Thread-119 consumed  Data 
Thread-116 produced  Data 
Thread-123 consumed  Data 
Thread-120 produced  Data 
Thread-124 consumed  Data 
Thread-121 produced  Data 
Thread-125 consumed  Data 
Thread-122 produced  Data 
Thread-129 consumed  Data 
Thread-126 produced  Data 
Thread-131 consumed  Data 
Thread-127 produced  Data 
Thread-135 consumed  Data 
Thread-132 produced  Data 
Thread-137 consumed  Data 
Thread-133 produced  Data 
Thread-136 consumed  Data 
Thread-128 produced  Data 
Thread-141 consumed  Data 
Thread-138 produced  Data 
Thread-143 consumed  Data 
Thread-134 produced  Data 
Thread-147 consumed  Data 
Thread-140 produced  Data 
Thread-149 consumed  Data 
Thread-146 produced  Data 
Thread-148 consumed  Data 
Thread-139 produced  Data 
Thread-153 consumed  Data 
Thread-144 produced  Data 
Thread-154 consumed  Data 
Thread-150 produced  Data 
Thread-155 consumed  Data 
Thread-151 produced  Data 
Thread-159 consumed  Data 
Thread-156 produced  Data 
Thread-160 consumed  Data 
Thread-157 produced  Data 
Thread-161 consumed  Data 
Thread-158 produced  Data 
Thread-165 consumed  Data 
Thread-152 produced  Data 
Thread-166 consumed  Data 
Thread-162 produced  Data 
Thread-167 consumed  Data 
Thread-163 produced  Data 
Thread-171 consumed  Data 
Thread-168 produced  Data 
Thread-172 consumed  Data 
Thread-169 produced  Data 
Thread-173 consumed  Data 
Thread-170 produced  Data 
Thread-177 consumed  Data 
Thread-164 produced  Data 
Thread-178 consumed  Data 
Thread-174 produced  Data 
Thread-179 consumed  Data 
Thread-175 produced  Data 
Thread-183 consumed  Data 
Thread-180 produced  Data 
Thread-184 consumed  Data 
Thread-181 produced  Data 
Thread-185 consumed  Data 
Thread-182 produced  Data 
Thread-189 consumed  Data 
Thread-176 produced  Data 
Thread-190 consumed  Data 
Thread-186 produced  Data 
Thread-191 consumed  Data 
Thread-187 produced  Data 
Thread-195 consumed  Data 
Thread-192 produced  Data 
Thread-196 consumed  Data 
Thread-193 produced  Data 
Thread-197 consumed  Data 
Thread-194 produced  Data 
Thread-201 consumed  Data 
Thread-188 produced  Data 
Thread-203 consumed  Data 
Thread-200 produced  Data 
Thread-202 consumed  Data 
Thread-145 produced  Data 
Thread-207 consumed  Data 
Thread-198 produced  Data 
Thread-208 consumed  Data 
Thread-206 produced  Data 
Thread-209 consumed  Data 
Thread-204 produced  Data 
Thread-213 consumed  Data 
Thread-205 produced  Data 
Thread-215 consumed  Data 
Thread-212 produced  Data 
Thread-214 consumed  Data 
Thread-199 produced  Data 
Thread-219 consumed  Data 
Thread-211 produced  Data 
Thread-220 consumed  Data 
Thread-218 produced  Data 
Thread-221 consumed  Data 
Thread-210 produced  Data 
Thread-225 consumed  Data 
Thread-222 produced  Data 
Thread-226 consumed  Data 
Thread-223 produced  Data 
Thread-227 consumed  Data 
Thread-224 produced  Data 
Thread-231 consumed  Data 
Thread-217 produced  Data 
Thread-232 consumed  Data 
Thread-228 produced  Data 
Thread-233 consumed  Data 
Thread-229 produced  Data 
Thread-237 consumed  Data 
Thread-234 produced  Data 
Thread-238 consumed  Data 
Thread-235 produced  Data 
Thread-239 consumed  Data 
Thread-236 produced  Data 
Thread-243 consumed  Data 
Thread-230 produced  Data 
Thread-244 consumed  Data 
Thread-240 produced  Data 
Thread-245 consumed  Data 
Thread-241 produced  Data 
Thread-249 consumed  Data 
Thread-246 produced  Data 
Thread-250 consumed  Data 
Thread-247 produced  Data 
Thread-251 consumed  Data 
Thread-248 produced  Data 
Thread-255 consumed  Data 
Thread-242 produced  Data 
Thread-257 consumed  Data 
Thread-258 produced  Data 
Thread-261 consumed  Data 
Thread-253 produced  Data 
Thread-263 consumed  Data 
Thread-254 produced  Data 
Thread-267 consumed  Data 
Thread-216 produced  Data 
Thread-268 consumed  Data 
Thread-264 produced  Data 
Thread-269 consumed  Data 
Thread-260 produced  Data 
Thread-273 consumed  Data 
Thread-270 produced  Data 
Thread-275 consumed  Data 
Thread-272 produced  Data 
Thread-274 consumed  Data 
Thread-265 produced  Data 
Thread-279 consumed  Data 
Thread-277 produced  Data 
Thread-281 consumed  Data 
Thread-266 produced  Data 
Thread-285 consumed  Data 
Thread-252 produced  Data 
Thread-286 consumed  Data 
Thread-282 produced  Data 
Thread-287 consumed  Data 
Thread-288 produced  Data 
Thread-292 consumed  Data 
Thread-289 produced  Data 
Thread-293 consumed  Data 
Thread-290 produced  Data 
Thread-297 consumed  Data 
Thread-276 produced  Data 
Thread-298 consumed  Data 
Thread-294 produced  Data 
Thread-299 consumed  Data 
Thread-295 produced  Data 


 

Reference

Java并发编程核心方法与框架

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值