zoukankan      html  css  js  c++  java
  • 《Java基础知识》Java 阻塞队列

    前言

    学习RabbitMQ的时候了解到了阻塞队列(ArrayBlockingQueue,LinkedBlockingDeque,SynchronousQueue),那就一起来了解一下这些阻塞队列。

    说明

    阻塞队列提供了四种处理方法:

    通过案例实现一个ArrayBlockingQueue的使用案例

    public class QueueTest {
        static ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(100000);
    
    
        public static void main(String[] args) {
            Runnable runnable0 = () -> {
                int i = 0;
                while(true){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("add:"+i);
                    arrayBlockingQueue.add(i++);
                }
            };
    
            Runnable runnable1 = () -> {
                int i = 0;
                while(true){
                    try {
                        Thread.sleep(200);
                        System.out.println("remove:"+arrayBlockingQueue.remove());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
    
            Thread thread0 = new Thread(runnable0);
            Thread thread1 = new Thread(runnable1);
            thread0.start();
            thread1.start();
        }
    }

    运行结果:

    队列使用基本都一致,不同的队列也是有一些区别的。

    SynchronousQueue:无缓冲队列,放入一个元素必须等其他线程获取之后才能再放入,用于阻塞线程的。

    通过案例看看SynchronousQueue如何使用

    public class SynQueueTest {
    
        static SynchronousQueue synchronousQueue = new SynchronousQueue();
    
    
        public static void main(String[] args) {
            Runnable runnable0 = () -> {
                while(true){
                    try {
                        Thread.sleep(100);
                        System.out.println("add");
                        synchronousQueue.put("add");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            };
    
            Runnable runnable1 = () -> {
                int i = 0;
                while(true){
                    try {
                        Thread.sleep(200);
                        System.out.println("take"+synchronousQueue.take());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
    
            Thread thread0 = new Thread(runnable0);
            Thread thread1 = new Thread(runnable1);
            thread0.start();
            thread1.start();
        }
    }

    运行结果:

    SynchronousQueue使用用来阻塞线程的,保证一对一匹配之后put 和 take 都释放。

    总结

    ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】

    LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的默认长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序,因为入队和出队不是同一锁,入队和出队不阻塞。

    PriorityBlockingQueue: 一个支持线程优先级排序的无界队列,默认自然序进行排序,也可以自定义实现compareTo()方法来指定元素排序规则,不能保证同优先级元素的顺序。

    SynchronousQueue:无缓冲队列,放入一个元素必须等其他线程获取之后才能再放入,用于阻塞线程的。

    ConcurrentLinkedQueue:非阻塞队列,通过自旋实现线程安全,不能被线程池中,性能消耗多。

    PriorityQueue:非线程安全,优先级队列,无界。

    DelayQueue:延迟队列,线程安全,阻塞,无界,到了时间之后才能取走。

  • 相关阅读:
    八皇后-递归
    代码复用3
    权限管理系统-角色组模块
    MzBlog分析
    linux shell 终端中文乱码(转)
    LINUX下中文语言包的安装(转)
    每一个程序员必须知道的业内英语词汇(转)
    80后创业故事之:兄弟散伙,创业失败(转)
    尊重用户的习惯审美,不要挑战用户的习惯(转)
    libpcre.so.1 cannot be found
  • 原文地址:https://www.cnblogs.com/jssj/p/13783053.html
Copyright © 2011-2022 走看看