青岛网站设计制作,宁波网站制作报价,博客app下载安装,不连接wordpress安装reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中#xff0c;队列的使用率很高#xff0c;多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻 塞队列和非阻塞队列#xff0c;其中阻…reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中队列的使用率很高多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻 塞队列和非阻塞队列其中阻塞队列的典型例子是BlockingQueue非阻塞队列的典型例子是ConcurrentLinkedQueue在实际 应用中要根据实际需要选用阻塞队列或者非阻塞队列。 注什么叫线程安全这个首先要明确。线程安全就是说多线程访问同一代码不会产生不确定的结果。 并行和并发区别 1、并行是指两者同时执行一件事比如赛跑两个人都在不停的往前跑2、并发是指资源有限的情况下两者交替轮流使用资源比如一段路(单核CPU资源)同时只能过一个人A走一段后让给BB用完继续给A 交替使用目的是提高效率 LinkedBlockingQueue由于LinkedBlockingQueue实现是线程安全的实现了先进先出等特性是作为生产者消费者的首选LinkedBlockingQueue 可以指定容量也可以不指定不指定的话默认最大是Integer.MAX_VALUE其中主要用到put和take方法put方法在队列满的时候 会阻塞直到有队列成员被消费take方法在队列空的时候会阻塞直到有队列成员被放进来。 package cn.thread;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;/*** 多线程模拟实现生产者消费者模型* * author 林计钦* version 1.0 2013-7-25 下午05:23:11*/
public class BlockingQueueTest2 {/*** * 定义装苹果的篮子* */public class Basket {// 篮子能够容纳3个苹果BlockingQueueString basket new LinkedBlockingQueueString(3);// 生产苹果放入篮子public void produce() throws InterruptedException {// put方法放入一个苹果若basket满了等到basket有位置basket.put(An apple);}// 消费苹果从篮子中取走public String consume() throws InterruptedException {// take方法取出一个苹果若basket为空等到basket有苹果为止(获取并移除此队列的头部)return basket.take();}}// 定义苹果生产者class Producer implements Runnable {private String instance;private Basket basket;public Producer(String instance, Basket basket) {this.instance instance;this.basket basket;}public void run() {try {while (true) {// 生产苹果System.out.println(生产者准备生产苹果 instance);basket.produce();System.out.println(!生产者生产苹果完毕 instance);// 休眠300msThread.sleep(300);}} catch (InterruptedException ex) {System.out.println(Producer Interrupted);}}}// 定义苹果消费者class Consumer implements Runnable {private String instance;private Basket basket;public Consumer(String instance, Basket basket) {this.instance instance;this.basket basket;}public void run() {try {while (true) {// 消费苹果System.out.println(消费者准备消费苹果 instance);System.out.println(basket.consume());System.out.println(!消费者消费苹果完毕 instance);// 休眠1000msThread.sleep(1000);}} catch (InterruptedException ex) {System.out.println(Consumer Interrupted);}}}public static void main(String[] args) {BlockingQueueTest2 test new BlockingQueueTest2();// 建立一个装苹果的篮子Basket basket test.new Basket();ExecutorService service Executors.newCachedThreadPool();Producer producer test.new Producer(生产者001, basket);Producer producer2 test.new Producer(生产者002, basket);Consumer consumer test.new Consumer(消费者001, basket);service.submit(producer);service.submit(producer2);service.submit(consumer);// 程序运行5s后所有任务停止
// try {
// Thread.sleep(1000 * 5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// service.shutdownNow();}}ConcurrentLinkedQueueConcurrentLinkedQueue是Queue的一个安全实现Queue中元素按FIFO原则进行排序采用CAS操作来保证元素的一致性。LinkedBlockingQueue 是一个线程安全的阻塞队列它实现了BlockingQueue接口BlockingQueue接口继承自java.util.Queue接口并在这 个接口的基础上增加了take和put方法这两个方法正是队列操作的阻塞版本。 package cn.thread;import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ConcurrentLinkedQueueTest {private static ConcurrentLinkedQueueInteger queue new ConcurrentLinkedQueueInteger();private static int count 2; // 线程个数//CountDownLatch一个同步辅助类在完成一组正在其他线程中执行的操作之前它允许一个或多个线程一直等待。private static CountDownLatch latch new CountDownLatch(count);public static void main(String[] args) throws InterruptedException {long timeStart System.currentTimeMillis();ExecutorService es Executors.newFixedThreadPool(4);ConcurrentLinkedQueueTest.offer();for (int i 0; i count; i) {es.submit(new Poll());}latch.await(); //使得主线程(main)阻塞直到latch.countDown()为零才继续执行System.out.println(cost time (System.currentTimeMillis() - timeStart) ms);es.shutdown();}/*** 生产*/public static void offer() {for (int i 0; i 100000; i) {queue.offer(i);}}/*** 消费* * author 林计钦* version 1.0 2013-7-25 下午05:32:56*/static class Poll implements Runnable {public void run() {// while (queue.size()0) {while (!queue.isEmpty()) {System.out.println(queue.poll());}latch.countDown();}}
}复制代码 运行结果costtime 2360ms 改用while (queue.size()0)后运行结果cost time 46422ms 结果居然相差那么大看了下ConcurrentLinkedQueue的API原来.size()是要遍历一遍集合的难怪那么慢所以尽量要避免用size而改用isEmpty(). 总结了下 在单位缺乏性能测试下对自己的编程要求更加要严格特别是在生产环境下更是要小心谨慎。转载于:https://www.cnblogs.com/awkflf11/articles/5179142.html