java 多线程队列

java队列方法很简单,就简单的 新增 add()/offer() 、 拿出 poll()、查看 peek(),这几种操作。
队列分为 阻塞的和非阻塞的,基本的用法都很简单,但是确是非常灵活。
Queue
    add();//如果队列已满,会抛出错误
    offer();//相当于add,如果队列已满,返回false
    remove();//删除第一个元素,集合为空时调用抛出异常
    poll();//删除第一个元素,集合为空时调用,返回null
    peek();//查询队列头部元素,空时null
    element();//查询队列头元素,空时报错
ConcurrentLinkedQueue 非阻塞队列

BlockingQueue 阻塞队列
        新增了:
        put();//如果满了,就会等待
        take();//如果空了,就会等待
        blockingQueue.offer("123",10,TimeUnit.MINUTES);//添加,如果添加不成功,10分钟后,程序阻塞

    LinkedBQ 阻塞队列 列表
    ArrayBQ 阻塞队列 数组
    DelayQueue 执行定时任务,只能添加实现了 Delayed接口的对象
    LinkedTransferQueue  等待消费者消费才能进行生产,有消费者时它会直接找消费者,没有就阻塞
        transferQueue.transfer();  与add/offer 生产者生产,如果无消费者,它会阻塞
    SynchronousQueue 继承 TransferQueue,容量为0的队列,只能有put,只有消费者消费完之后才能进行put

非阻塞队列实现消费者和生产者模式


    //非阻塞的队列
    static Queue<String> linkedQueue = new ConcurrentLinkedQueue<>();//线程安全的队列
    /**
     * 简单的售票问题 非阻塞队列
     */
   static void linkedQueueTest() {
        System.out.println("初始化 共有100张票");
        for (int i = 0 ;i < 100;i++ ){
//            linkedQueue.add(i+"");//add 和 offer 都是往队列里面添加元素,add如果元素满了会报错,offer如果元素满了,会返回false
            linkedQueue.offer(i+"");
        }
        //买票窗口
       for (int i=0;i<5;i++){
           //此线程对queue只有一个原子操作 poll,是线程安全的,不会产生多线程问题
           new Thread(()->{
               while (true){
                   String str = linkedQueue.poll();
                   if(str == null){
                       System.out.println("票已经卖完");
                       break;
                   }
                   System.out.print(str +",");
               }
           }).start();
       }
    }

双端队列实现 分类优先模式


    //双端队列
    static Deque<Integer> dequeQueue = new ConcurrentLinkedDeque<>();//线程安全的队列

    /**
     * 用双端队列实现 小孩优先
     */
    public static void dequeTest(){
        //初始化
        for (int i=0;i<100;i++){
            Integer randomInt = new Random().nextInt(100);
            if(randomInt <= 14){
                //小于14岁的,放在前面
                dequeQueue.offerFirst(randomInt);
            }else {
                dequeQueue.offerLast(randomInt);
            }
        }
        //出列
        while (true){
            Integer t = dequeQueue.poll();
            if(t == null){
                break;
            }
            System.out.print(t + ",");
        }
    }

用阻塞队列实现生产者-消费者模式

/**
     * 用阻塞队列实现 消费者-生产者模式
     * 生产者一直生产 ,直到仓库满了 就阻塞,消费者一直消费,直到仓库空了就阻塞
     BlockingQueue 阻塞队列
     新增了:
     put();//如果满了,就会等待
     take();//如果空了,就会等待
     blockingQueue.offer("123",10,TimeUnit.MINUTES);//添加,如果添加不成功,10分钟后,程序阻塞
     */
    public static void blockQueueTest(){
        //阻塞队列
         BlockingQueue blockingQueue = new ArrayBlockingQueue(10);

         //三个线程在生产
         for (int i=0;i<3;i++){
             new Thread(()->{
                 while (true) {
                     try {
                         Thread.sleep(2000);
                         blockingQueue.put("good");//生产物品 如果满了,就等待消费
                         System.out.println("生产物品 size:"+blockingQueue.size());
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }).start();
         }
         //消费者线程
        for (int i=0;i<5;i++) {
            new Thread(()->{
                while (true) {
                    try {
                        Thread.sleep(3000);
                        blockingQueue.take();//阻塞消费,如果空,等待消费
                        System.out.println("消费了一个物品 size:"+blockingQueue.size());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

延时队列 实现定时任务


    /**
     * 延时队列  只能添加实现了 Delayed接口的对象,
     * 可做定时任务的处理
     */
    static void delayQueueTest(){
        DelayQueue<MyDelayBead> delayQueue = new DelayQueue();
        delayQueue.put(new MyDelayBead("1",3));//任务1 3秒后执行
        delayQueue.put(new MyDelayBead("2",1));//任务2 1秒后执行
        delayQueue.put(new MyDelayBead("3",5));//任务3 5秒后执行
        while (true){
            MyDelayBead myDelayBead = null;
            try {
                myDelayBead = delayQueue.take();
                System.out.println("现在时间:"+System.currentTimeMillis()+" "+myDelayBead.toString());
                if(delayQueue.size() == 0){
                    System.out.println("队列全部已经出列");
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    static class MyDelayBead implements Delayed {
        int delaySecond;//延迟秒数
        String task;//任务名
        long createTime;//创建时间

        @Override
        public String toString() {
            return "MyDelayBead{" +
                    "delaySecond=" + delaySecond +
                    ", task='" + task + '\'' +
                    ", createTime=" + createTime +" delay:"+getDelay(TimeUnit.MILLISECONDS)+
                    '}';
        }

        MyDelayBead(String task, int delaySecond){
            this.task = task;
            this.delaySecond = delaySecond;
            this.createTime = System.currentTimeMillis();
        }

        /**
         * 还有多长时间就可以往外拿了,注意需要使用现在的时间
         */
        @Override
        public long getDelay(TimeUnit unit) {
            long targetTime = createTime + delaySecond * 1000;
            return unit.convert( targetTime - System.currentTimeMillis() ,TimeUnit.MILLISECONDS);
//            return delaySecond * 1000;
        }

        @Override
        public int compareTo(Delayed o) {
            if(this.getDelay(TimeUnit.MILLISECONDS ) > o.getDelay(TimeUnit.MILLISECONDS)){
                return 1;
            }else if(this.getDelay(TimeUnit.MILLISECONDS ) == o.getDelay(TimeUnit.MILLISECONDS)){
                return 0;
            }else{
                return -1;
            }
        }
        //getter and setter

        public int getDelaySecond() {
            return delaySecond;
        }

        public void setDelaySecond(int delaySecond) {
            this.delaySecond = delaySecond;
        }

        public String getTask() {
            return task;
        }

        public void setTask(String task) {
            this.task = task;
        }

        public long getCreateTime() {
            return createTime;
        }

        public void setCreateTime(long createTime) {
            this.createTime = createTime;
        }
    }

上诉延迟队列的执行结果:

现在时间:1582008218242 MyDelayBead{delaySecond=1, task='2', createTime=1582008217240 delay:-2}
现在时间:1582008220240 MyDelayBead{delaySecond=3, task='1', createTime=1582008217240 delay:0}
现在时间:1582008222241 MyDelayBead{delaySecond=5, task='3', createTime=1582008217240 delay:-1}
队列全部已经出列

注意geDelay()重写时,需要结果调用的当前时间,意为距离当前还需要多久执行。

用TransferQueue实现 生产者-消费者模式,生产者需要等待消费者消费才生产

 /**
     * TransferQueue的生产者-消费者模式
     * transferQueue.transfer(); 只有消费者消费才进行生产
     */
    public static void transferQueueTest(){
        //生产者 只有消费者消费才能进行生产
        TransferQueue<String> transferQueue = new LinkedTransferQueue();
        //生产者 2个
        for (int i=0;i<2;i++){
            new Thread(()->{
                while (true) {
                    try {
                        //1秒生产一个
                        Thread.sleep(1000);
                        transferQueue.transfer("生产1个物品");//有消费者消费才进行生产
                        System.out.println("生产者生产 size:"+transferQueue.size());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        //消费者 5个
        for (int i=0;i<1;i++){
            new Thread(()->{
                while (true) {
                    try {
                        Thread.sleep(5000);
                        transferQueue.take();
                        System.out.println("消费者消费 size:"+transferQueue.size());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
发布了60 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/xiaoluo5238/article/details/104374753