Java并发工具包之印象篇一
转摘于 http://www.importnew.com/26461.html
1、BlockingQueue
BlockingQueue通常用于一个线程生产对象,而另外一个线程消费这些对象的场景。 一个线程往里放,另外一个线程从里取得一个BlockingQueue。
一个线程将会持续生产新对象并将其插入到队列之中,直到队列达到它所能容纳的临界点。即它的大小是有限的。如果该阻塞队列达到了其临界点,负责生产的线程将会在插入新对象的时候阻塞。它会一直处于阻塞之中,直到负责消费的线程从队列中拿走一个对象。负责消费的线程将会一直从该阻塞队列中拿出对象。如果消费者尝试去从一个空的队列中提取对象的话,那么消费线程将会处于阻塞之中,直到队列里面有对象可消费为止。
抛异常: 如果试图的操作无法立即执行,抛一个异常
特定之:如果试图的操作无法立即执行,返回一个特定的值(一般为true/false)
阻塞:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行
超时:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但会有一个时间等待,时间不会超过给定的值。
无法向一个BlockingQueue中插入null。 将会抛出NPE。 可以访问到BlockingQueue中的所有元素,而不仅仅是开始和结束的元素。比如说,将一个对象放入队列中等待处理,但你的应用想要将其取消掉。那么可以调用remove(o)方法来操作。但这样做的效率不高,因此尽量不要使用这一类方法。
BlockingQueue是一个接口,需要使用它的实现之一。 java.util.concurrent具有以下BlockingQueue接口的实现java6
1、ArrayBlocking 2、DelayQueue 3、LinkedBlockingQueue 4、PriorityBlockingQueue 5、SynchronousQueue
首先,BlockingQueueExample类分别在两个独立的线程启动一个producer和一个consumer。producer向一个共享的BlockingQueue中注入字符串,而Consumer则从中获取
public class BlockingQueueExample { public static void main(String[] args) throws Exception { BlockingQueue queue = new ArrayBlockingQueue(1024); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); new Thread(producer).start(); new Thread(consumer).start(); Thread.sleep(4000); } }
Producer类。每次put调用时休眠一秒钟,导致Consumer在等待队列中对象的时候发生阻塞
public class Producer implements Runnable{ protected BlockingQueue queue = null; public Producer(BlockingQueue queue) { this.queue = queue; } public void run() { try { queue.put("1"); Thread.sleep(1000); queue.put("2"); Thread.sleep(1000); queue.put("3"); } catch (InterruptedException e) { e.printStackTrace(); } } }
Consumer类,从队列中获取对象,并打印
public class Consumer implements Runnable{ protected BlockingQueue queue = null; public Consumer(BlockingQueue queue) { this.queue = queue; } public void run() { try { System.out.println(queue.take()); System.out.println(queue.take()); System.out.println(queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } } }
2、数组阻塞队列ArrayBlockingQueue
它是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,存储有限数量的元素。可以在其初始化的时候设置这个上限值,但之后就无法修改这个上限值(数组的特性)。 ArrayBlockingQueue内部以FIFO先进先出的顺序对元素进行存储。队列中的头元素在所有元素之中是放入时间最久的那个。
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1024);
queue.put("1");
String str = queue.take();
3、延迟队列DelayQueue
DelayQueue对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现java.util.concurrent.Delayed接口,该接口定义
public interface Delayed extends Comarable<Delayed> {
public long getDelay(TimeUnit timeUnit);
}
DelayQueue将会在每个元素的getDelay方法返回的值得时间段之后才释放该元素,如果返回的是0或者负值,延迟将被认为过期,该元素将会在DelayQueue的下一次take被调用的时候被释放掉。传递给getDelay方法的getDelay实例是一个枚举类型,表明将要延迟的时间段。
TimeUnit 枚举将会取以下值:
DAYS
HOURS
MINUTES
SECONDS
MILLISECONDS
MICROSECONDS
NANOSECONDS