队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。 抛出异常 返回特殊值 插入 add(e) offer(e) 移除 remove() poll() 检查 element() peek() Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回值可以判断成功与否, add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用element()或者peek()方法。 element方法是在队列为空的时候抛异常,而peek则是返回null。 LinkedList类实现了Queue接口 public class QueueTest { public static void main(String[] args) { // add()和remove()方法在失败的时候会抛出异常(不推荐) Queue<String> queue = new LinkedList<String>(); // 添加元素 queue.offer("a"); queue.offer("b"); queue.offer("c"); queue.offer("d"); queue.offer("e"); for (String q : queue) { System.out.println(q); } System.out.println("==="); System.out.println("poll=" + queue.poll()); // 返回第一个元素,并在队列中删除 for (String q : queue) { System.out.println(q); } System.out.println("==="); System.out.println("element=" + queue.element()); // 返回第一个元素 for (String q : queue) { System.out.println(q); } System.out.println("==="); System.out.println("peek=" + queue.peek()); // 返回第一个元素 for (String q : queue) { System.out.println(q); } } } BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作 2. 当队列空了的时候进行出队列操作 BlockingQueue四个接口,接口定义的方法如下: Throws Exception Special Value Blocks Times Out 插入 add(o) offer(o) put(o) offer(o, timeout, timeunit) 移除 remove(o) poll() take() poll(timeout, timeunit) 检查 element() peek() 这四套方法对应的特点分别是: BlockingQueue 方法以四种形式出现, 对于不能立即满足但可能在将来某一时刻可以满足的操作, 这四种形式的处理方式不同:第一种是抛出一个异常, 第二种是返回一个特殊值(null 或 false,具体取决于操作), 第三种是在操作可以成功前,无限期地阻塞当前线程, 第四种是在放弃前只在给定的最大时间限制内阻塞 BlockingQueue的实现类 1. ArrayBlockingQueue 2. DelayQueue 3. LinkedBlockingQueue 4. PriorityBlockingQueue 5. SynchronousQueue ArrayBlockingQueue是一个有边界的阻塞队列,它的内部实现是一个数组。有边界的意思是它的容量是有限的,我们必须在其初始化的时候指定它的容量大小,容量大小一旦指定就不可改变。 LinkedBlockingQueue阻塞队列大小的配置是可选的,如果我们初始化时指定一个大小,它就是有边界的,如果不指定,它就是无边界的。说是无边界,其实是采用了默认大小为Integer.MAX_VALUE的容量 它的内部实现是一个链表。 PriorityBlockingQueue是一个没有边界的队列,它的排序规则和 java.util.PriorityQueue一样。需要注意,PriorityBlockingQueue中允许插入null对象。 所有插入PriorityBlockingQueue的对象必须实现 java.lang.Comparable接口,队列优先级的排序规则就是按照我们对这个接口的实现来定义的。 SynchronousQueue队列内部仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费。 DelayQueue 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的, 即队头对象的延迟到期的时间最长。如果没有任何延迟到期,那么就不会有任何头元素,并且poll将返回null(正因为这样,不能将 null放置到这种队列中). DelayQueue阻塞的是其内部元素,DelayQueue中的元素必须实现 java.util.concurrent.Delayed接口,这个接口的定义非常简单: public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); } getDelay()方法的返回值就是队列元素被释放前的保持时间,如果返回0或者一个负值,就意味着该元素已经到期需要被释放,此时DelayedQueue会通过其take()方法释放此对象。 从上面Delayed 接口定义可以看到,它还继承了Comparable接口,这是因为DelayedQueue中的元素需要进行排序,一般情况,我们都是按元素过期时间的优先级进行排序。 PriorityBlockingQueue示例: public class PriorityElement implements Comparable<PriorityElement> { private int priority;// 定义优先级 PriorityElement(int priority) { // 初始化优先级 this.priority = priority; } @Override public int compareTo(PriorityElement o) { // 按照优先级大小进行排序 return priority >= o.getPriority() ? 1 : -1; } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } @Override public String toString() { return "PriorityElement [priority=" + priority + "]"; } } public class PriorityBlockingQueueExample { public static void main(String[] args) throws InterruptedException { PriorityBlockingQueue<PriorityElement> queue = new PriorityBlockingQueue<PriorityElement>(); for (int i = 0; i < 5; i++) { Random random=new Random(); PriorityElement ele = new PriorityElement(random.nextInt(10)); queue.put(ele); } while(!queue.isEmpty()){ System.out.println(queue.take()); } } } 参考文章:http://blog.csdn.net/suifeng3051/article/details/48807423 管道流(pipeStream)是种特殊的流,用于在不同线程间传送数据,一个线程一端发送数据到管道,另外一个线程从输入管道读取 管道流有两种: 字符流:PipedReader、PipedWriter 字节流:PipedInputStrean、PipedOutputStram import java.io.IOException; import java.io.PipedReader; import java.io.PipedWriter; public class PipedWriteTest { public static class ThradPipedReaderA extends Thread { PipedReader pipedReader; public ThradPipedReaderA(PipedReader pipedReader) { this.pipedReader = pipedReader; } @Override public void run() { try { char[] chararray = new char[20]; int readLenth = pipedReader.read(chararray); while (readLenth != -1) { String str = new String(chararray, 0, readLenth); System.out.println("读到的数据为:" + str); readLenth = pipedReader.read(chararray); } pipedReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static class ThradPipedWriteB extends Thread { PipedWriter pipedWriter; public ThradPipedWriteB(PipedWriter pipedWriter) { this.pipedWriter = pipedWriter; } @Override public void run() { try { for (int i = 0; i <= 10; i++) { pipedWriter.write("发送数据" + i); } pipedWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) throws IOException { PipedReader pipedReader = new PipedReader(); PipedWriter pipedWriter = new PipedWriter(); pipedReader.connect(pipedWriter);// 做个链接才能通讯 ThradPipedReaderA a = new ThradPipedReaderA(pipedReader); ThradPipedWriteB b = new ThradPipedWriteB(pipedWriter); a.start(); b.start(); } }
Java 队列Queue
猜你喜欢
转载自yangeoo.iteye.com/blog/2410992
今日推荐
周排行