ArrayBlockingQueue使用

 阻塞与非阻塞:

  阻塞:

    阻塞调用是没有获得资源则挂起进程,被挂起的进程进入休眠状态,调用的函数只有在得到结果之后才返回,进程继续。

    对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但并不是一一对应的;阻塞对象上可以有非阻塞的调用方式。

    我们可以通过一定的API去轮询状态,在适当的时候调用阻塞函数,就可以避免阻塞。

  非阻塞:

    非阻塞是不能进行设备操作时不挂起,或返回,或反复查询,直到可以进行操作为止,被调用的函数不会阻塞当前进程,而会立刻返回。

    对于非阻塞对象,调用的函数也可以锁机制进入阻塞调用 

  注意:

    阻塞不是低效率,如果设备驱动不阻塞,用户想获取资源只能不断查询,小号CPU阻塞访问时,不能获取资源的进程将进入休眠,将CPU资源让给其他资源。

    阻塞的进程会进入休眠状态,因此,必须确保有一个地方能唤醒休眠的进程。唤醒进程的地方最大可能发生在终端里面,因为硬件资源的获得往往伴随着一个终端。

  

案例代码:主线程生产日志数据,由多线程去消费

public class ArrayBlockingQueueTest {
    
    public static void main(String[] args) throws Exception {
        //创建一个固定大小的队列 
        final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
        //生产数据
        for(int i=0;i<100000;i++){  
            queue.put(i+1+"");
        }
        //创建10个消费者
        for(int i=0;i<10;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true){
                        try {
                            String log = queue.take();
                            System.out.println(Thread.currentThread().getName()+"=>"+log);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }
 
}


结果输出:

  Thread-0=>1
  Thread-3=>3
  Thread-2=>4
  Thread-1=>2
  Thread-3=>6
  Thread-1=>7
  Thread-0=>5
  Thread-1=>8
  Thread-2=>9
  Thread-2=>10
  Thread-3=>11
  Thread-3=>12
  Thread-1=>13
  Thread-2=>14

 

 

put原理:

    /**
     * Inserts the specified element at the tail of this queue, waiting
     * for space to become available if the queue is full.
     *
     * @throws InterruptedException {@inheritDoc}
     * @throws NullPointerException {@inheritDoc}
     */
    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }

 

take原理:

    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue();
        } finally {
            lock.unlock();
        }
    }

 

转载于:https://www.cnblogs.com/weishao-lsv/p/8143714.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值