(二)线程池原理分析-JAVA阻塞队列生产者线程与消费者模型

阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列.

1、ArrayBlockingQueue

      基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象时必须制定容量大小。并且可以指定公平性与非公平性,默认情况下为非公平的,即不保证等待时间最长的队列最优先能够访问队列。

2、LinkedBlockingQueue

     基于链表实现的一个阻塞队列,在创建LinkedBlockingQueue对象时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。

3、PriorityBlockingQueue

       以上2种队列都是先进先出队列,而PriorityBlockingQueue却不是,它会按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都是优先级最高的元素。注意,此阻塞队列为无创作中心 界阻塞队列,即

容量没有上限(通过源码就可以知道,它没有容器满的信号标志),前面2种都是有界队列。

4、DelayQueue

       基于PriorityQueue,一种延时阻塞队列,DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue也是一个无界队列,因此往队列中插入数据的操作(生产者)永远不会

生产者线程

/**
 * 生产者线程
 * @author Administrator
 *
 */
public class Demo50ProducerThread implements Runnable {

    private BlockingQueue<String> blockingQueue;
    private volatile boolean FLAG = true;
    private AtomicInteger atomicInteger  = new AtomicInteger();
    
    public Demo50ProducerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }


    @Override
    public void run() {
        System.out.println("####生产者线程已经启动#####");
        
        try {
            while(FLAG) {
                Integer data = atomicInteger.incrementAndGet();
                boolean offer = blockingQueue.offer(data.toString(), 2, TimeUnit.SECONDS);
                if(offer) {
                    System.out.println("生产者存入队列成功! data:"+data);
                }else {
                    System.out.println("生产者存入队列失败! data:"+data);
                }
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("####生产者线程已经结束#####");
        }
        
    }
    
    public void stop() {
        this.FLAG = false;
    }

}

消费者线程

/**
 * 消费者线程
 * @author Administrator
 *
 */
public class Demo50ConsumerThread implements Runnable{
    
    private BlockingQueue<String> blockingQueue;
    private volatile boolean FLAG = true;
    
    public Demo50ConsumerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    public void run() {
        System.out.println("####消费者线程已经启动#####");
        try {
            while(FLAG) {
                String data = blockingQueue.poll(2, TimeUnit.SECONDS);
                if(data==null) {
                    System.out.println("消费者线程超过2s,没有获取队列信息");
                    FLAG = false;
                    return ;
                }
                System.out.println("消费者线程获取数据data:"+data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("####消费者线程已经停止#####");
        }
    }
}

测试类

public class Demo50BlockingQueueMain {

    public static void main(String[] args) {
        LinkedBlockingQueue<String> linkedBlockQueue = new LinkedBlockingQueue<String>(10);
        Demo50ProducerThread demo50ProducerThread = new Demo50ProducerThread(linkedBlockQueue);
        Demo50ConsumerThread Demo50ConsumerThread = new Demo50ConsumerThread(linkedBlockQueue);
        new Thread(demo50ProducerThread).start();
        new Thread(Demo50ConsumerThread).start();
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        demo50ProducerThread.stop();
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值