玖叶教程网

前端编程开发入门

BlockingQueue 阻塞队列

BlockingQueue 继承关系图:


阻塞队列的使用场景:多线程并发处理,线程池。

队列的使用操作:添加、移除

操作的4组API:

1、抛出异常

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 阻塞队列测试
 */
public class BlockingQueueDemo {

    public static void main(String[] args) {

        // 设置指定队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        //=============队列新增
        System.out.println( blockingQueue.add( "A" ) );
        System.out.println( blockingQueue.add( "B" ) );
        System.out.println( blockingQueue.add( "C" ) );
        //java.lang.IllegalStateException: Queue full 抛出异常
        //System.out.println( blockingQueue.add( "D" ) );

        //=============队列移除
        System.out.println( blockingQueue.remove() );
        System.out.println( blockingQueue.remove() );
        System.out.println( blockingQueue.remove() );
        //java.util.NoSuchElementException 抛出异常
        System.out.println( blockingQueue.remove() );
    }
    
}

如上述代码,在我们add与remove操作中,数据添加超过队列大小或者队列里面没有数据时均会抛出异常。

2、有返回值,不抛出异常

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 阻塞队列测试
 */
public class BlockingQueueDemo {

    public static void main(String[] args) {

        // 设置队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        //=============队列offer
        System.out.println( blockingQueue.offer( "A" ) );
        System.out.println( blockingQueue.offer( "B" ) );
        System.out.println( blockingQueue.offer( "C" ) );
        //返回false
        System.out.println( blockingQueue.offer( "D" ) );

        //=============队列poll
        System.out.println( blockingQueue.poll() );
        System.out.println( blockingQueue.poll() );
        System.out.println( blockingQueue.poll() );
        //结果返回null
        System.out.println( blockingQueue.poll() );
    }

}

如上述代码,在我们add与remove操作中,数据添加超过队列大小时会返回flase,队列为空时进行poll结果会返回null;

3、 阻塞,等待

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 阻塞队列测试
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {

        // 设置队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        //=============队列put
        blockingQueue.put( "A" ) ;
        blockingQueue.put( "B" ) ;
        blockingQueue.put( "C" ) ;
        //返回false
       // blockingQueue.put( "D" ) ;

        //=============队列take
        System.out.println( blockingQueue.take() );
        System.out.println( blockingQueue.take() );
        System.out.println( blockingQueue.take() );
        //这里会阻塞,知道有数据
        System.out.println( blockingQueue.take() );
    }

}

如上述代码,在我们put与take操作中,数据添加超过队列大小时会一直阻塞直到能够put成功后再结束,当队列为空时进行poll一直会阻塞到队列里面有值才结束;

通过源码我们可以看到,阻塞队列是通过lock锁与Condition进行线程间的通讯去实现的;

4、超时等待


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 阻塞队列测试
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {

        // 设置队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        //=============队列新增
        blockingQueue.offer( "A" ,2 , TimeUnit.SECONDS) ;
        blockingQueue.offer( "B" ,2 , TimeUnit.SECONDS) ;
        blockingQueue.offer( "C"  ,2 , TimeUnit.SECONDS) ;
        //等待2秒没有队列没有空闲位置结束offer
        blockingQueue.offer( "D"  ,2 , TimeUnit.SECONDS) ;

        //=============队列移除
        System.out.println( blockingQueue.poll(2,TimeUnit.SECONDS));
        System.out.println( blockingQueue.poll(2,TimeUnit.SECONDS));
        System.out.println( blockingQueue.poll(2,TimeUnit.SECONDS));
        //等待2秒没数据停止poll
        System.out.println( blockingQueue.poll(2,TimeUnit.SECONDS));
    }

}

不管是offer还是poll,在指定的时间内没有队列中没有空闲大小或者没有数据时,会停止当前操作,运行其他任务等。




通过源码我们可以看到,也是用到了Condition类中的awaitNanos方法。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言