标签:java多线程
offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,
则返回true,否则返回false.(本方法不阻塞当前执行方法的线程)
offer(E o, long timeout, TimeUnit unit),可以设定等待的时间,如果在指定的时间内,还不能往队列中
加入BlockingQueue,则返回失败。
put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断
直到BlockingQueue里面有空间再继续.
引自:http://blog.csdn.net/vernonzheng/article/details/8247564
1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的.
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的
3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.
4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.
其中LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue.
package concurrency; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class BlockingQueueTest { // 定义装苹果的篮子,用BlockingQueue模拟 public static class Basket{ // 篮子,能够装5个苹果 // ArrayBlockingQueue必须有容量限制 private final BlockingQueue<String> basket=new ArrayBlockingQueue<String>(5); // 生产苹果 public void produce(){ try{ basket.put("An apple"); }catch(InterruptedException e){ e.printStackTrace(); } } // 消费苹果 public String consume(){ String str=null; try{ str=basket.take(); }catch(InterruptedException e){ e.printStackTrace(); } return str; } } // 测试方法 public static void testBasket(){ // 实例化篮子 final Basket basket=new Basket(); // 定义苹果生产者 class Producer implements Runnable{ public void run(){ while(true){ // 生产苹果 System.out.println("准备生产苹果:"+ System.currentTimeMillis()); basket.produce(); System.out.println("生产苹果完毕:"+ System.currentTimeMillis()); try{ Thread.sleep(300); }catch(InterruptedException e){ e.printStackTrace(); } } } } // 定义苹果消费者 class Consumer implements Runnable{ public void run(){ while(true){ // 消费苹果 System.out.println("准备消费苹果:"+ System.currentTimeMillis()); basket.consume(); System.out.println("消费苹果完毕:"+ System.currentTimeMillis()); try{ Thread.sleep(500); }catch(InterruptedException e){ e.printStackTrace(); } } } } ExecutorService exec=Executors.newCachedThreadPool(); Producer producer=new Producer(); Consumer consumer=new Consumer(); exec.execute(producer); exec.execute(consumer); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 强行终止正在执行的线程,shutdown等待正在执行的线程结束,等待列表的线程不再执行 exec.shutdownNow(); } public static void main(String[] args){ testBasket(); } }
准备生产苹果:1428121675968 生产苹果完毕:1428121675968 准备消费苹果:1428121675968 消费苹果完毕:1428121675968 准备生产苹果:1428121676265 生产苹果完毕:1428121676265 准备消费苹果:1428121676468 消费苹果完毕:1428121676468 准备生产苹果:1428121676562 生产苹果完毕:1428121676562 准备生产苹果:1428121676874 生产苹果完毕:1428121676874 准备消费苹果:1428121676968 消费苹果完毕:1428121676968 准备生产苹果:1428121677171 生产苹果完毕:1428121677171 准备消费苹果:1428121677468 消费苹果完毕:1428121677468 准备生产苹果:1428121677468 生产苹果完毕:1428121677468 准备生产苹果:1428121677765 生产苹果完毕:1428121677765 准备消费苹果:1428121677968 消费苹果完毕:1428121677968 准备生产苹果:1428121678078 生产苹果完毕:1428121678078 准备生产苹果:1428121678374 生产苹果完毕:1428121678374 准备消费苹果:1428121678468 消费苹果完毕:1428121678468 准备生产苹果:1428121678671 生产苹果完毕:1428121678671 准备消费苹果:1428121678968 消费苹果完毕:1428121678968 准备生产苹果:1428121678968 生产苹果完毕:1428121678968 准备生产苹果:1428121679281 生产苹果完毕:1428121679281 准备消费苹果:1428121679468 消费苹果完毕:1428121679468 准备生产苹果:1428121679578 生产苹果完毕:1428121679578 准备生产苹果:1428121679874 准备消费苹果:1428121679968 生产苹果完毕:1428121679968 消费苹果完毕:1428121679968 准备生产苹果:1428121680265 准备消费苹果:1428121680468 消费苹果完毕:1428121680468 生产苹果完毕:1428121680468 准备生产苹果:1428121680765 java.lang.InterruptedException: sleep interrupted 生产苹果完毕:1428121680968 准备消费苹果:1428121680968 消费苹果完毕:1428121680968 at java.lang.Thread.sleep(Native Method) at concurrency.BlockingQueueDemo$1Consumer.run(BlockingQueueDemo.java:66) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(Unknown Source) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source) at java.util.concurrent.ArrayBlockingQueue.put(Unknown Source) at concurrency.BlockingQueueDemo$Basket.produce(BlockingQueueDemo.java:17) at concurrency.BlockingQueueDemo$1Producer.run(BlockingQueueDemo.java:44) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) 准备生产苹果:1428121681265 生产苹果完毕:1428121681265 准备消费苹果:1428121681468 消费苹果完毕:1428121681468 准备生产苹果:1428121681578 生产苹果完毕:1428121681578 准备生产苹果:1428121681874 准备消费苹果:1428121681968 消费苹果完毕:1428121681968 生产苹果完毕:1428121681968 准备生产苹果:1428121682265
package concurrency; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; /** * @author jackyuj */ public class BlockingQueueTest { public static void main(String[] args) throws InterruptedException { // 声明一个容量为10的缓存队列 BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10); Producer producer1 = new Producer(queue); Producer producer2 = new Producer(queue); Producer producer3 = new Producer(queue); Consumer consumer = new Consumer(queue); // 借助Executors ExecutorService service = Executors.newCachedThreadPool(); // 启动线程 service.execute(producer1); service.execute(producer2); service.execute(producer3); service.execute(consumer); // 执行10s Thread.sleep(10 * 1000); producer1.stop(); producer2.stop(); producer3.stop(); Thread.sleep(2000); // 退出Executor service.shutdown(); } }
package concurrency; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * 生产者线程 * * @author jackyuj */ public class Producer implements Runnable { public Producer(BlockingQueue queue) { this.queue = queue; } public void run() { String data = null; Random r = new Random(); System.out.println("启动生产者线程!"); try { while (isRunning) { System.out.println("正在生产数据..."); Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP)); data = "data:" + count.incrementAndGet(); System.out.println("将数据:" + data + "放入队列..."); if (!queue.offer(data, 2, TimeUnit.SECONDS)) { System.out.println("放入数据失败:" + data); } } } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } finally { System.out.println("退出生产者线程!"); } } public void stop() { isRunning = false; } private volatile boolean isRunning = true; private BlockingQueue queue; private static AtomicInteger count = new AtomicInteger(); private static final int DEFAULT_RANGE_FOR_SLEEP = 1000; }
package concurrency; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; /** * 消费者线程 * * @author jackyuj */ public class Consumer implements Runnable { public Consumer(BlockingQueue<String> queue) { this.queue = queue; } public void run() { System.out.println("启动消费者线程!"); Random r = new Random(); boolean isRunning = true; try { while (isRunning) { System.out.println("正从队列获取数据..."); String data = queue.poll(2, TimeUnit.SECONDS); if (null != data) { System.out.println("拿到数据:" + data); System.out.println("正在消费数据:" + data); Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP)); } else { // 超过2s还没数据,认为所有生产线程都已经退出,自动退出消费线程。 isRunning = false; } } } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } finally { System.out.println("退出消费者线程!"); } } private BlockingQueue<String> queue; private static final int DEFAULT_RANGE_FOR_SLEEP = 1000; }
启动生产者线程! 正在生产数据... 启动消费者线程! 正从队列获取数据... 启动生产者线程! 正在生产数据... 启动生产者线程! 正在生产数据... 将数据:data:1放入队列... 正在生产数据... 拿到数据:data:1 正在消费数据:data:1 将数据:data:2放入队列... 正在生产数据... 将数据:data:3放入队列... 正在生产数据... 将数据:data:4放入队列... 正在生产数据... 将数据:data:5放入队列... 正在生产数据... 正从队列获取数据... 拿到数据:data:2 正在消费数据:data:2 将数据:data:6放入队列... 正在生产数据... 正从队列获取数据... 拿到数据:data:3 正在消费数据:data:3 将数据:data:7放入队列... 正在生产数据... 将数据:data:8放入队列... 正在生产数据... 将数据:data:9放入队列... 正在生产数据... 将数据:data:10放入队列... 正在生产数据... 将数据:data:11放入队列... 正在生产数据... 将数据:data:12放入队列... 正在生产数据... 正从队列获取数据... 拿到数据:data:4 正在消费数据:data:4 将数据:data:13放入队列... 正在生产数据... 正从队列获取数据... 拿到数据:data:5 正在消费数据:data:5 将数据:data:14放入队列... 正在生产数据... 将数据:data:15放入队列... 正在生产数据... 正从队列获取数据... 拿到数据:data:6 正在消费数据:data:6 正从队列获取数据... 拿到数据:data:7 将数据:data:16放入队列... 正在消费数据:data:7 正在生产数据... 将数据:data:17放入队列... 正在生产数据... 将数据:data:18放入队列... 正从队列获取数据... 拿到数据:data:8 正在消费数据:data:8 正在生产数据... 正从队列获取数据... 拿到数据:data:9 正在消费数据:data:9 将数据:data:19放入队列... 正在生产数据... 将数据:data:20放入队列... 将数据:data:21放入队列... 正从队列获取数据... 拿到数据:data:10 正在消费数据:data:10 正在生产数据... 将数据:data:22放入队列... 将数据:data:23放入队列... 正从队列获取数据... 正在生产数据... 拿到数据:data:11 正在消费数据:data:11 正从队列获取数据... 拿到数据:data:12 正在消费数据:data:12 正在生产数据... 正从队列获取数据... 拿到数据:data:13 正在消费数据:data:13 正在生产数据... 将数据:data:24放入队列... 将数据:data:25放入队列... 将数据:data:26放入队列... 正从队列获取数据... 拿到数据:data:14 正在消费数据:data:14 正在生产数据... 将数据:data:27放入队列... 正从队列获取数据... 正在生产数据... 拿到数据:data:15 正在消费数据:data:15 正从队列获取数据... 正在生产数据... 拿到数据:data:16 正在消费数据:data:16 正从队列获取数据... 正在生产数据... 拿到数据:data:17 正在消费数据:data:17 将数据:data:28放入队列... 将数据:data:29放入队列... 将数据:data:30放入队列... 正从队列获取数据... 正在生产数据... 拿到数据:data:18 正在消费数据:data:18 正从队列获取数据... 正在生产数据... 拿到数据:data:19 正在消费数据:data:19 将数据:data:31放入队列... 正从队列获取数据... 拿到数据:data:20 正在生产数据... 正在消费数据:data:20 将数据:data:32放入队列... 正从队列获取数据... 拿到数据:data:21 正在生产数据... 正在消费数据:data:21 将数据:data:33放入队列... 正从队列获取数据... 拿到数据:data:22 正在消费数据:data:22 正在生产数据... 将数据:data:34放入队列... 正从队列获取数据... 拿到数据:data:23 正在消费数据:data:23 退出生产者线程! 将数据:data:35放入队列... 正从队列获取数据... 退出生产者线程! 拿到数据:data:24 正在消费数据:data:24 正从队列获取数据... 拿到数据:data:25 退出生产者线程! 正在消费数据:data:25 正从队列获取数据... 拿到数据:data:26 正在消费数据:data:26 正从队列获取数据... 拿到数据:data:27 正在消费数据:data:27 正从队列获取数据... 拿到数据:data:28 正在消费数据:data:28 正从队列获取数据... 拿到数据:data:29 正在消费数据:data:29 正从队列获取数据... 拿到数据:data:30 正在消费数据:data:30 正从队列获取数据... 拿到数据:data:31 正在消费数据:data:31 正从队列获取数据... 拿到数据:data:32 正在消费数据:data:32 正从队列获取数据... 拿到数据:data:33 正在消费数据:data:33 正从队列获取数据... 拿到数据:data:34 正在消费数据:data:34 正从队列获取数据... 拿到数据:data:35 正在消费数据:data:35 正从队列获取数据... 退出消费者线程!
标签:java多线程
原文地址:http://blog.csdn.net/ldrmcml/article/details/44871963