http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html转载他人 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 注:什么叫线程安全?这个首先要明确。线程安全就是说多线程访问同一代码,不会产生不确定的结果。 并行和并发区别 1、并行是指两者同时执行一件事,比如赛跑,两个人都在不停的往前跑; 2、并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给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个苹果 BlockingQueue<String> basket = new LinkedBlockingQueue<String>(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); // 休眠300ms Thread.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); // 休眠1000ms Thread.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(); } } 复制代码 ConcurrentLinkedQueue ConcurrentLinkedQueue是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 ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>(); 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(). 总结了下, 在单位缺乏性能测试下,对自己的编程要求更加要严格,特别是在生产环境下更是要小心谨慎。
相关推荐
根据提供的文件信息:“JAVA并发编程实战.pdf”,我们可以深入探讨与Java并发编程相关的多个核心知识点。 ### Java并发编程基础 #### 1. 并发与并行 - **并发(Concurrency)**:指一个程序中存在多个执行序列(如...
总结,Java中的JSON序列化与反序列化是数据交互的重要环节,Jackson和Gson是两个常用的库,它们提供了丰富的功能和良好的API设计,使得处理JSON数据变得简单高效。通过理解和掌握这些知识,开发者可以更好地在Java...
在Java应用程序中,如果需要在MySQL环境中实现类似Oracle序列的功能,我们需要自己设计解决方案。以下是一些关键知识点的详细说明: 1. **Java连接MySQL**: - 首先,你需要使用JDBC(Java Database Connectivity...
标准的Java序列化虽然方便,但在处理大量数据时,性能往往成为瓶颈。这时,FST(Fast Serialization Toolkit)作为一个高效且JDK兼容的序列化库,提供了更快的速度和更小的内存占用,成为了Java开发者的一个优秀选择...
- 如果可能,利用多核处理器的优势,使用并发或并行处理来加速序列化和反序列化。 5. **预编译序列化代码**: - 使用`-Xbootclasspath/a:`参数指定自定义的`serializabilityPolicy`,可以预先生成序列化代码,...
Java并发编程是Java开发中的核心领域,尤其在多核处理器越来越普遍的今天,理解和掌握并发编程技巧至关重要。本篇主要探讨了Java并发编程中的基本概念、优缺点、线程与进程的区别以及线程的状态转换。 首先,我们来...
6. **实时处理**:Java的多线程和并发特性使得在处理实时信号流时表现优秀,可以实现实时音频、视频的捕获、处理和播放。 7. **图像处理**:Java数字信号处理也可以应用于图像领域,例如图像的灰度化、二值化、平滑...
3. **异常处理**:Java提供了强大的异常处理机制,用于捕获和处理运行时错误。了解如何使用try-catch-finally语句块以及不同类型的异常类是必不可少的。 4. **集合框架**:Java集合框架包括接口(如List、Set、Map...
Java序列化相对较慢,对于高并发和大数据量的场景,可能需要考虑其他的序列化库,如FST、Kryo或Google的Protobuf等。这些库提供更快的速度和更小的序列化数据大小。 7. **Netty与协议**: Netty支持多种协议,如...
Java并发编程是构建高效、可扩展的多线程应用程序的关键技术。开源软件Amino,作为Apache旗下的一员,为Java并发编程提供了强大的支持。Amino设计的主要目标是提高并发操作的可操作性和伸缩性,同时保持跨平台的兼容...
除此之外,你还需要关注Java并发编程,理解线程同步、锁机制,以及并发容器如ConcurrentHashMap的使用。Java集合框架的深入理解,如ArrayList、LinkedList、HashMap等的实现原理,能帮助你更好地选择适合的数据结构...
线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进程所创建的对象资源(内存资源)。java.lang.Thread对象负责统计和控制这种行为。 每个程序都至少...
例如,使用ConcurrentHashMap进行并发支持度计算,或者利用并行流(Parallel Streams)加速数据处理。 总之,GSP算法是数据挖掘序列模式领域的基石之一,它的Java实现为实际业务场景提供了强大的工具。通过理解和...
Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 Spring面试题 Spring Boot面试题 Spring Cloud面试题 RabbitMQ面试题 Dubbo 面试题 MyBatis ...
7. **反射机制**:Java的反射API允许在运行时动态访问类、接口、字段和方法,这对于插件化开发、序列化、动态代理等场景很有用。 8. **设计模式**:源码中常常会体现各种设计模式,如工厂模式、单例模式、观察者...
除了基本的序列化和反射,此项目可能还涉及到其他相关技术,如数据访问对象(DAO)模式用于与数据库交互,MVC(模型-视图-控制器)设计模式用于结构化应用程序,以及可能的多线程处理以支持并发预订操作。...
使用说明 首先在Pom文件中引入依赖,如下 ... <artifactId>Fse <version>1.0 API 使用方式如下 Fse fse = new Fse(); TestData data = new TestData();...Fse不是并发安全的。多个线程需要使用多个实例来进行调用。
Netty提供了一个`SerializationCodec`类,它是`ChannelInboundHandler`和`ChannelOutboundHandler`的实现,专门用于处理Java序列化的编码和解码。在编码过程中,`SerializationCodec`会调用`ObjectOutputStream`将...
java解决分布式环境中高并发环境下数据插入重复问题 本文主要介绍了java解决分布式环境中高并发环境下数据插入重复问题的解决方案。该问题是指在高并发环境下,服务器同时接受到的重复请求,导致数据重复插入或修改...