阻塞队列使用方式详解
阅读原文时间:2021年04月20日阅读:1

阻塞队列

方法\处理方式

抛出异常

返回特殊值

一直阻塞

超时退出

插入方法

add(e)

offer(e)

put(e)

offer(e,time,unit)

移除方法

remove()

poll()

take()

poll(time,unit)

检查方法

element()

peek()

不可用

不可用

抛出异常:

   生产者在add时当队列满时会抛出异常;消费者当队列空时会抛出异常

返回特殊值:线程不会被阻塞

  生产者在offer的时候,如果队列满时会返回false;消费者当队列空时会返回null

一直阻塞:

   生产者在put时当队列满时会一直等待,知道队列不满、响应中断退出;消费者当队列空时会一直等待,直到有数据或者响应中断

超时退出:

   生产者在offer时,如果队列满时会等待time时间,单位是unit,如果等待这些时间后仍然是满的会返回false;消费者当队列空时会等待time时间,单位是unit,如果仍然是空会返回null

注意:

返回特殊值和一直阻塞的区别是,如果是offer/poll当不满足条件时不会被阻塞,而是直接返回true或者false  null或者具体值,而put/take会一直被阻塞

put/take

public class QueryTest {
    static ArrayBlockingQueue<String> query = new ArrayBlockingQueue<String>(4);
    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        query.put(i + "");
                        System.out.println(Thread.currentThread().getName()+"---put suc");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(200);
                    System.out.println(Thread.currentThread().getName()+" 获取数据--->" + query.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        try {
            Thread.sleep(2000000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

结果:

Thread-0---put suc
Thread-0---put suc
Thread-0---put suc
Thread-0---put suc
Thread-1 获取数据--->0
Thread-0---put suc//阻塞,等待满足条件

offer/take

public class QueryTest {
    static ArrayBlockingQueue<String> query = new ArrayBlockingQueue<String>(4);

    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
//                        query.put(i + "");
//                        System.out.println(Thread.currentThread().getName()+"---put suc");
                        System.out.println(query.offer(i + "")+"---put suc "+i);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(200);
                    System.out.println(Thread.currentThread().getName()+" 获取数据--->" + query.poll());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        try {
            Thread.sleep(2000000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

结果:

true---put suc 0
true---put suc 1
true---put suc 2
true---put suc 3
false---put suc 4//没有被阻塞而是直接运行
false---put suc 5
false---put suc 6
false---put suc 7
false---put suc 8
false---put suc 9
Thread-1 获取数据--->0