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 
 
4、链阻塞队列LinkedBlockingQueue
其内部以一个链式结构对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用Integer.MAX_VALUE作为上限。
LinkedBlockingQueue内部以FIFO(先进先出)的顺序对元素进行存储。队列中的头元素在所有元素之中是放入时间最久的那个,那尾元素则是最短的那个。
 
BlockingQueue<String> bounded = new LinkedBlockingQueue<String>(1024);
bounded.put("123");
String value = bounded.take();
 
5、具有优先级的阻塞队列PriorityBlockingQueue
它是一个无界的并发队列。不能插入null之。所有插入到该队列的元素必须实现 java.lang.Comparable接口。
 
BlockingQueue queue = new PriorityBlocingQueue();
queue.put("value");
String value = queue.take();
 
6、同步队列SynchronousQueue
它是一个特殊的队列,它的内部同事只能容纳单个元素。如果队列中已有一个元素的话,试图插入一个新元素的线程将会被阻塞,直到另一个线程将该元素从队列中取走。同样,队列为空的话,试图从队列中取出一个元素的话也将会阻塞,直到另一个线程向队列中插入一个新元素。
 
==================================================
 
1、阻塞双端队列BlockingDeque
 
该接口表示一个线程放入和提取实例的双端队列。 双端队列是一个可以从任意一端插入或者抽取元素的队列。该接口继承自BlockingQueue接口。
 
java.util.concurrent包提供了以下BlockingDeque接口的实现类: LinkedBlockingDeque
 
BlockingDeque<String> deque = new LinkedBlockingDeque<String>();
deque.addFirst("1");
deque.addLast("2");
 
String one = deque.takeLast();
String two = deque.takeFirst();
 
 
posted @ 2018-05-15 15:13  秋水秋色  阅读(93)  评论(0编辑  收藏  举报