首页 > 技术文章 > 队列的插入 和出列 阻塞 时间 问题

wzhanke 2015-08-27 16:44 原文

 

 一、向队列里插入 数据:

final BlockingQueue<Integer> test = new ArrayBlockingQueue<Integer>(1);
        test.offer(1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("test => " + test);
                    Thread.sleep(5000);
                    System.out.println("test => " + test);
                    test.poll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        System.out.println("test1 == " + test);
        test.offer(2, 10, TimeUnit.SECONDS);
        System.out.println("test2 == " + test);


总结:由于队列大小是一定的,当插入的时候,队列已经满了,不能再插入了,结果在执行完再次插入的代码“test.offer(2, 10, TimeUnit.SECONDS);” 后

@线程开始阻塞10s

@本次向插入的2仍然没有插入进去

@当阻塞的10s还未到期时如果队列突然又不满了的话,线程开始自动不阻塞(应该是当队列一不满就会有东西回调通知此阻塞的线程不要阻塞了,队列已不满了,可以继续本次插入操作了)本次插入操作立即执行即这个2 会被立即插入进去,不用等到10s到期

@当10s到期后队列还是满的话,那本次插入请求失败,线程退出阻塞状态,代码继续 从在“test.offer(2, 10, TimeUnit.SECONDS);” 这句代码后边代码开始执行。

@总结-即你做的插入操作我只能最多等你10s,如果在这10s内什么时候可以插入就给你完成本次插入,否则一直阻塞,但我不可能一直阻塞等你,10s后我就不管你了,10s后我就跳过本次插入代码继续向下执行了。

@总结-阻塞只会阻塞一次,阻塞时间到立马不再阻塞。阻塞时间内可插入时立马唤醒,继续完成本次插入操作,否则一旦阻塞时间到期后就跳过本次插入操作。

 

 二、 向队列里插入 数据:

final BlockingQueue<Integer> test = new ArrayBlockingQueue<Integer>(1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("test1 => " + test);
                    Thread.sleep(5000);
                    test.offer(1);
                    System.out.println("test => " + test);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        test.poll(10, TimeUnit.SECONDS);
        System.out.println("test2 == " + test);

总结:当做出列操作时如果列表为空,如果还想出列操作,那就会在代码“test.poll(10, TimeUnit.SECONDS);

@线程开始阻塞10s

@当阻塞的10s还未到期时如果队列突然有值的话,线程开始自动不阻塞(应该是当队列一有值就会有东西回调通知此阻塞的线程不要阻塞了,队列有值了,可以继续本次插入操作了)本次出列操作立即执行,即把队里刚有的值给出列了,不用等到10s到期

@当10s到期后队列还是空的话,那本次出列请求失败,线程退出阻塞状态,代码继续 从在“test.poll(10, TimeUnit.SECONDS);” 这句代码后边代码开始执行。

@总结-即你做的出列操作我只能最多等你10s,如果在这10s内什么时候可以出列操作就给你完成本次出列操作,否则一直阻塞,但我不可能一直阻塞等你,10s后我就不管你了,10s后我就跳过本次出列代码继续向下执行了。

@总结-阻塞只会阻塞一次,阻塞时间到立马不再阻塞。阻塞时间内可出列时立马唤醒,继续完成本次出列操作,否则一但阻塞时间到期后就跳过本次出列操作。

 

总结:不管是插入还是处理 操作,针对的都是本次操作,本次操作能立即完成就不会阻塞,如阻塞的话在阻塞时间内一但可以完成操作,阻塞线程会被唤醒,完成未完成的本次操作。否则等到阻塞时间到期后,本次操作作废,阻塞线程也不再阻塞,自动唤醒后继续执行后边的代码。

上边针对的都是 带时间参数的,假如不带时间参数的插入和出列 操作,当操作不成功后会立即有反馈结果,线程不会被阻塞住,插入return的结果为true/false,而出列的结果为出列的元素值或null,即出列成功了那return的就是被出列的那个元素,出列失败的return即返回null。

 

推荐阅读