JDK1.5 Queue
LinkedList:
LinkedList不是同步的。如果多个线程同时访问列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法来“包装”该列表。最好在创建时完成这一操作,以防止对列表进行意外的不同步访问,如下所示:
List list = Collections.synchronizedList(new LinkedList(...));
将指定元素追加到列表的结尾有add、offer两个方法,区别是offer是接口 Queue<E>中的,add是接口 Collection<E> 中的。offer使用可能有插入限制(例如容量限定)的队列时,offer方法通常要优于 Collection.add(E) 方法,因为add只能通过抛出异常使插入元素失败。而offer方法的返回值是:如果可以向此队列添加元素,则返回 true;否则返回 false。
找到并移除列表的头(第一个元素)有poll、remove两个方法,区别是poll是接口 Queue<E>中的,remove是接口 Queue<E>中的。如果队列为空,poll返回null,而remove抛出NoSuchElementException。
找到但不移除列表的头(第一个元素)是peek方法
实例:
package com.bijian.thread; import java.util.LinkedList; import java.util.Queue; public class UseLinkedList { public static void main(String[] args) { Queue<String> queue = new LinkedList<String>(); queue.offer("Hello"); queue.offer("World!"); queue.offer("你好!"); System.out.println(queue.size()); String str; while ((str = queue.poll()) != null) { System.out.println(str); } System.out.println(); System.out.println(queue.size()); } }
运行结果:
3 Hello World! 你好! 0
ArrayBlockingQueue:
一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。
ArrayBlockingQueue的常用方法:
put:将指定的元素添加到此队列的尾部,如果必要,将等待可用的空间。
take:检索并移除此队列的头部,如果此队列不存在任何元素,则一直等待。
offer:将指定的元素插入到此队列的尾部(如果可能),如果此队列已满,则立即返回。
poll:检索并移除此队列的头,如果此队列为空,则返回null。
说明:put、offer都是向队列中添加元素,take、poll都是从队列中移除元素。put和take对应一组,是阻塞式的;offer、poll对应一组,是非阻塞式的。
实例:
package com.bijian.thread.blockqueue; import java.util.concurrent.BlockingQueue; public class Producer implements Runnable { private final BlockingQueue<Character> queue; Producer(BlockingQueue<Character> q) { queue = q; } public void run() { try { for (int i = 0; i < 10; i++) { queue.put(produce()); System.out.println("生产后:" + queue.peek()); } } catch (Exception e) { e.printStackTrace(); } } Character produce() { char c = (char) (Math.random() * 26 + 'A'); System.out.println("生产前:" + c); return c; } }
package com.bijian.thread.blockqueue; import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable { private String name; private final BlockingQueue<Character> queue; public Consumer(String name, BlockingQueue<Character> q) { this.name = name; this.queue = q; } @Override public void run() { try { while(true) { consume(queue.take()); } } catch(InterruptedException e) { e.printStackTrace(); } } public void consume(Character c) { System.out.println("[" + name + "]消费: " + c); } }
package com.bijian.thread.blockqueue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class Main { /** * @param args */ public static void main(String[] args) { BlockingQueue q = new ArrayBlockingQueue(10); Producer p = new Producer(q); Consumer c1 = new Consumer("tom", q); Consumer c2 = new Consumer("jacky", q); new Thread(c1).start(); new Thread(c2).start(); new Thread(p).start(); } }
运行结果(打印结束后程序一直未结束,但也未输出,处于阻塞状态):
生产前:L 生产后:L 生产前:Q [tom]消费: L [jacky]消费: Q 生产后:Q 生产前:G 生产后:G [tom]消费: G 生产前:O 生产后:O [jacky]消费: O 生产前:M 生产后:M [tom]消费: M 生产前:I 生产后:I [jacky]消费: I 生产前:B 生产后:B 生产前:Q [tom]消费: B [jacky]消费: Q 生产后:Q 生产前:D 生产后:D [tom]消费: D 生产前:A 生产后:A [jacky]消费: A
实例2:
package com.bijian.thread.blockqueue; import java.util.concurrent.BlockingQueue; public class Producer implements Runnable { private final BlockingQueue<Character> queue; Producer(BlockingQueue<Character> q) { queue = q; } public void run() { try { for (int i = 0; i < 10; i++) { queue.offer(produce()); //System.out.println("生产后:" + queue.peek()); } } catch (Exception e) { e.printStackTrace(); } } Character produce() { char c = (char) (Math.random() * 26 + 'A'); System.out.println("生产前:" + c); return c; } }
package com.bijian.thread.blockqueue; import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable { private String name; private final BlockingQueue<Character> queue; public Consumer(String name, BlockingQueue<Character> q) { this.name = name; this.queue = q; } @Override public void run() { while(true) { consume(queue.poll()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void consume(Character c) { System.out.println("[" + name + "]消费: " + c); } }
package com.bijian.thread.blockqueue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class Main { /** * @param args */ public static void main(String[] args) { BlockingQueue q = new ArrayBlockingQueue(10); Producer p = new Producer(q); Consumer c1 = new Consumer("tom", q); Consumer c2 = new Consumer("jacky", q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } }
运行结果(打印结束后程序一直未结束,消费者一直输出null,处于非阻塞状态):
[tom]消费: null [jacky]消费: null 生产前:S 生产前:R 生产前:N 生产前:S 生产前:P 生产前:U 生产前:J 生产前:Y 生产前:C 生产前:H [jacky]消费: S [tom]消费: R [jacky]消费: N [tom]消费: S [tom]消费: P [jacky]消费: U [jacky]消费: J [tom]消费: Y [jacky]消费: C [tom]消费: H [jacky]消费: null [tom]消费: null [tom]消费: null [jacky]消费: null ……
DelayQueue:
Delayed 元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满。此队列不允许使用 null 元素。
DelayQueue的常用方法:
add:将指定元素添加到此队列中。
offer:将指定元素插入到此延迟队列中。
put:将指定元素添加到此延迟队列中。由于该队列是无界的,所以此方法永远不会阻塞。
take:检索并移除此队列的头部,如果此队列不存在未到期延迟的元素,则等待它。
poll:检索并移除此队列的头部,如果此队列不存在未到期延迟的元素,则返回null。
remove:从此队列中移除指定元素的单个实例(如果存在)。
drainTo:移除此队列中所有可用的元素,并将它们添加到给定 collection 中。
实例:
package com.bijian.thread.blockqueue.delayqueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class NanoDelay implements Delayed { private String name; private long targetTime; public NanoDelay(String name, long targetTime) { super(); this.name = name; this.targetTime = TimeUnit.NANOSECONDS.convert(targetTime, TimeUnit.NANOSECONDS); } @Override public int compareTo(Delayed o) { NanoDelay that = (NanoDelay)o; return targetTime > that.targetTime?1:(targetTime < that.targetTime?-1:0); } @Override public long getDelay(TimeUnit unit) { return unit.convert(targetTime, unit.NANOSECONDS); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("NanoDelay [name="); builder.append(name); builder.append(", targetTime="); builder.append(targetTime); builder.append("]"); return builder.toString(); } }
package com.bijian.thread.blockqueue.delayqueue; import java.util.Random; import java.util.concurrent.DelayQueue; public class Main { public static void main(String args[]) { Random random = new Random(); DelayQueue<NanoDelay> queue = new DelayQueue<NanoDelay>(); for (int i = 0; i < 5; i++) { queue.add(new NanoDelay("T" + i, random.nextInt(5))); } System.out.println("start.."); System.out.println(queue.size()); for(int i = 0; i < 5; i++) { try { NanoDelay delay = queue.take(); System.out.println(delay); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果(打印结束后程序一直未结束,但也未输出,处于阻塞状态):
start.. 5 NanoDelay [name=T1, targetTime=0]
相关推荐
11. **泛型**:泛型引入于JDK1.5,用于提高代码的类型安全性和重用性,理解泛型类、泛型方法和通配符的使用。 12. **枚举**:枚举是JDK1.5引入的新特性,用于定义一组固定的值,可以替代传统的常量类。 13. **异常...
- 在这种模式下,客户端通过队列(Queue)将消息发送到另一个客户端。 - 发送消息的客户端将消息放入特定的队列中。 - 接收消息的客户端从该队列中提取消息。 - 每个消息只能被一个消费者接收。 2. **发布订阅...
ConcurrentQueue ConcurrentStack .NET API 系统 班级 大批 动作 Func 例外 GC 特性最大生成 方法 收集(Int32) CollectionCount(Int32) GetGeneration(对象) GetTotalMemory(布尔) ...
Name Server是RocketMQ的重要组件之一,主要负责管理主题(Topic)和队列(Queue)的元数据,以及提供Producer和Consumer的路由信息。 在作者的操作过程中,遇到了以下问题: 1. 当试图通过`nohup sh bin/mqnamesrv...
在JDK1.5以前Java集合会丢失容器中所有对象的数据类型,把所有对象都当初object对象来处理,JDK1.5以后增加了泛型,Java集合可以记住容器中对象的数据类型。从而可以编写出更简洁,健壮的代码。
3. **java.util**:这个包提供了一组实用工具类,包括集合框架(如ArrayList、LinkedList、HashMap)、日期/时间操作(如Date、Calendar)、随机数生成(Random)、队列(Queue)等。集合框架是Java编程中不可或缺的...
此外,`Callable`接口在JDK 1.5后引入,它可以返回一个结果,并且可以抛出异常,相比`Runnable`更具有优势。 线程的状态管理是多线程编程中非常重要的部分。Java线程有六种状态:NEW、RUNNABLE、BLOCKED、WAITING、...
在JDK 1.8中,集合框架已经相当成熟和完善,包括List、Set、Queue、Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。本篇文章将深入探讨这些集合类的源码,揭示其内部实现机制。 首先,我们来看`...
- **字符串拼接**:在进行字符串拼接时,如果是在循环中拼接字符串,应该使用`StringBuilder`(JDK 1.5及以上版本)或`StringBuffer`(线程安全),而不是使用`+`操作符,因为后者会导致频繁的对象创建和垃圾回收。...
7. **JDK 1.5新特性**: - 包括泛型,枚举,自动装箱拆箱,可变参数,增强的for循环(foreach)等,这些极大地提高了代码的可读性和安全性。 8. **多线程**: - Java提供了内置的多线程支持,通过创建Thread对象...
- JDK版本特性:关注JDK1.5、JDK1.6、JDK1.7、JDK1.8等各版本的新特性和提升。 **三、数据库相关** - 理论基础:了解数据库设计原则、范式和事务的基本概念和工作原理。 - 数据库操作:学习MySQL、SQLServer、...
首先,需要准备好JMS环境,包括JMS 1.1、Apache ActiveMQ 5.4.0、Spring 2.5.4、JDK 1.5和MyEclipse 7.5。 其次,需要创建一个Java项目,包括src/main/java和src/main/resources两个文件夹。在classpath中,需要...
- **JDK版本更新**:对比JDK1.5至JDK1.8的新特性,如自动装箱拆箱、枚举、泛型、并发工具类等改进。 通过系统学习以上知识点,并结合实际项目经验,你将逐渐积累深厚的技术底蕴,成为一名Java开发领域的专家。记住...
JDK 1.5后引入了自动装箱和拆箱功能,使得基本类型和包装类之间的转换更为便捷。 5. Collection集合 `Collection`接口是所有单列集合的父接口,它定义了集合的基本操作,如添加、删除和遍历元素。集合与数组的主要...
这个压缩包文件"JDK1.5API_CN(ȫ).CHM"是Java 1.5版本的中文API帮助文档,通常以CHM(Compiled HTML Help)格式存储,这种格式便于离线查看和搜索。 在Java API中,我们可以找到以下主要知识点: 1. **基础类库**...
自JDK 1.5起,Java引入了泛型,使得集合可以限制其存储的元素类型,提高代码的类型安全性和效率。通过在集合声明时指定泛型参数,可以确保插入和取出的元素类型一致。 3. **常用接口与实现类** - `List`接口:最...
2. **开发平台**:使用JDK 1.5版本,这是编写和运行Java程序的基础。 四、设计思路 1. **界面构建** - 使用JFrame作为基础窗口,设置大小、关闭行为、是否可调整大小,并添加标题。 - 通过BorderLayout布局管理...
增强型for循环(JDK 1.5引入): 增强型for循环,也称为foreach循环,简化了遍历集合的操作。然而,它不支持在迭代过程中修改集合,否则可能会抛出ConcurrentModificationException。 总的来说,熟练掌握Java基础,...
首先,Collection接口主要有List、Set和Queue三种子接口。List接口用于存储有序且可重复的集合元素,常用的实现类有ArrayList和LinkedList。ArrayList底层是基于动态数组实现的,适合快速随机访问,但插入和删除操作...