Java阻塞队列_BlockingQueue

Java阻塞队列_BlockingQueue

Java阻塞队列_BlockingQueue_第1张图片


以上是BlockingQueue所有的方法。。

 add(anObject):把anObject加到BlockingQueue里,如果BlockingQueue可以容纳,则返回true,否则抛出异常。 

 offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false。 

 put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。 

 poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null。 

take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。 


BlockingQueue的子接口和实现类

BlockingQueue继承自Queue接口

All Known Subinterfaces:

BlockingDeque<E>, TransferQueue<E>

All Known Implementing Classes:

ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue


java.ulil.concurrent包提供了阻塞队列的4个变种

默认情况下,LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。


ArrayBlockingQueue在构造时需要指定容量, 并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。


PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。


最后,DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。


使阻塞队列实现生产者和消费者模式

代码示例,生产者

package container;

import java.util.concurrent.BlockingQueue;

public class Fetcher implements Runnable {
    private BlockingQueue<String> queue = null;

    public Fetcher(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            int i = 0;
            while (true) {
                // put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,
                // 则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。
                queue.put("segment-name-" + i);
                System.out.println("ThreadName : " + Thread.currentThread().getName() + " 抓取完成");
                i++;
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

消费者

package container;

import java.util.concurrent.BlockingQueue;

public class Indexer implements Runnable {

    private BlockingQueue<String> queue = null;

    public Indexer(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            while (true) {
                Thread.sleep(1000);
                //  take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,
                // 阻断进入等待状态直到BlockingQueue有新的对象被加入为止。
                String name = queue.take();
                System.out.println("ThreadName : " + Thread.currentThread().getName() + " 索引创建完成 " + name);
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

测试:

package container;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestConsumer {

    private static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);

    public static void main(String[] args) {

        //使用Executors创建一个线程池
        ExecutorService service = Executors.newCachedThreadPool();
        Fetcher producer = new Fetcher(queue); //生产者
        Indexer consumer0 = new Indexer(queue);
        Indexer consumer1 = new Indexer(queue);
        service.submit(producer);
        service.submit(consumer0);
        service.submit(consumer1);
        // 程序运行5s后,所有任务停止
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.shutdownNow();
    }
}

====END====

你可能感兴趣的:(Java阻塞队列_BlockingQueue)