精华内容
下载资源
问答
  • SynchronousQueue是无界的,是一种无缓冲的阻塞队列,插入操作必须等待令一个线程取数据,反之亦然(SynchronousQueue是线程安全的,是阻塞的)。同步队列没有任何内部容量,甚至连一个队列的容量都没有。 公平模式...

    BlockingQueue

    synchronousQueue学习

    SynchronousQueue是无界的,是一种无缓冲的阻塞队列,插入操作必须等待令一个线程取数据,反之亦然(SynchronousQueue是线程安全的,是阻塞的)。同步队列没有任何内部容量,甚至连一个队列的容量都没有。

    公平模式: 
    SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;

    非公平模式(SynchronousQueue默认): 
    SynchronousQueue采用非公平锁,同时配合一个LIFO队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。

    注意: 
    (1)不能在同步队列上进行 peek,因为仅在试图要取得元素时,该元素才存在; 
    (2)除非另一个线程试图移除某个元素,否则也不能(使用任何方法)添加元素; 
    (3)不能迭代队列 
    (4)该队列的头是尝试添加到队列的首个已排队插入线程的元素;如果没有这样的已排队线程,则没有可用于移除的元素并且pool方法将返回null 
    (5)不允许 null 元素 
    对于其他 Collection 方法(例如 contains)SynchronousQueue 作为一个空集合。 
    (6)同步队列类似于传递性的设计,即一个线程中运行的对象要将某些信息/事件/任务传递给另一个线程中运行的对象-->同步 
    (7)SynchronousQueue构造方法中可指定fairness的策略.如果fair,则等待线程以FIFO的顺序竞争访问;否则顺序是未指定的

    • SynchronousQueue方法

    • iterator() 永远返回空,因为里面没东西。

    • peek() 永远返回null。

    • put() 往queue放进去一个element以后就一直wait直到有其他thread进来把这个element取走。

    • offer() 往queue里放一个element后立即返回,如果碰巧这个element被另一个thread取走了,offer方法返回true,认为offer成功;否则返回false。

    • offer(2000, TimeUnit.SECONDS) 往queue里放一个element但是等待指定的时间后才返回,返回的逻辑和offer()方法一样。

    • take() 取出并且remove掉queue里的element(认为是在queue里的。。。),取不到东西他会一直等。

    • poll() 取出并且remove掉queue里的element(认为是在queue里的。。。),只有到碰巧另外一个线程正在往queue里offer数据或者put数据的时候,该方法才会取到东西。否则立即返回null。

    • poll(2000, TimeUnit.SECONDS) 等待指定的时间然后取出并且remove掉queue里的element,其实就是再等其他的thread来往里塞。

    • isEmpty()永远是true。

    • remainingCapacity() 永远是0。

    • remove()和removeAll() 永远是false。

    注意:

    (1)SynchronousQueue中没有空间,那么资源会会以最快的方式从生产者传递给消费者。 

    (2)SynchronousQueue中维护着生产者和消费者线程队列,既然有队列,同样就有公平性和非公平性特性,公平性保证正在等待的插入线 程或者移除线程以FIFO的顺序传递资源

    优先级队列PriorityBlockingQueue

    PriorityBlockingQueue里面存储的对象必须是实现Comparable接口。队列通过这个接口的compare方法确定对象的priority。
    规则是:当前和其他对象比较,如果compare方法返回负数,那么在队列里面的优先级就比较搞。
    /**
     * 
     * 
     * QueenTest
     * 创建人:LBM
     * 时间:2016年11月29日-上午10:54:16 
     * @version 1.0.0
     *
     */
    public class QueenTest {
    	public static void main(String[] args) {
    		PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<Task>();//创建一个优先级队列
    		Task task1 = new Task();
    		task1.setId(50);
    		Task task2 = new Task();
    		task2.setId(30);
    		Task task3 = new Task();
    		task3.setId(23);
    		Task task4 = new Task();
    		task4.setId(100);
    //		像优先级队列中插入三个对象
    		queue.put(task1);
    		queue.put(task2);
    		queue.put(task3);
    		queue.put(task4);
    		for (Task task : queue) {
    			System.out.println("循环打印队列,查看队列顺序"+task.getId());
    		}
    			try {
    				System.out.println("每次take后,查看队列顺序"+queue);
    				System.out.println(queue.take().getId());
    				System.out.println("每次take后,查看队列顺序"+queue);
    				System.out.println(queue.take().getId());
    				System.out.println("每次take后,查看队列顺序"+queue);
    				System.out.println(queue.take().getId());
    				System.out.println("每次take后,查看队列顺序"+queue);
    				System.out.println(queue.take().getId());
    			} catch (Exception e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    	} 
    }
    //创建一个类实现Comparable方法
    class Task implements Comparable<Task>{
    	
    	private int id;
    	private String name;
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	//实现compareTo方法
    	public int compareTo(Task task) {
    		//当新元素的id小于旧元素的时候,优先级比较高
    		if (task.id > this.id) {
    			return -1;
    		}
    		else if (task.id < this.id) {
    			return 1;
    		}else {
    			return 0;
    		}
    	}
    	//重写toString方法
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		return this.id+"";
    	}
    }
    
    打印结果

    我们知道我们插入的这组数据,数据最小的优先级越高,按照我们的想法,那我们存储的队列顺序应该是【23,30,50,100】但是真实的顺序却是【23,50,30,100】这是为什么呢 ?
    原来在PriorityBlockingQueue内部只能保证第一个取出的元素是优先级最高的元素,并不能保证队列内部所有元素都按照优先级去排序,当我们每次take的时候,这个队列就会重新再内部调用compareTo方法,然后保证队首的那个元素是优先级最高的元素。


    展开全文
  • java队列理解

    2020-12-15 20:56:46
    SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法...

    线程池ThreadPoolExecutor的三种队列SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue

    SynchronousQueue 同步队列

    SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null。
    声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。公平模式和非公平模式的区别:

    如果采用公平模式:SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;

    但如果是非公平模式(SynchronousQueue默认):SynchronousQueue采用非公平锁,同时配合一个LIFO队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。

    LinkedBlockingQueue 无界阻塞队列

    LinkedBlockingQueue是无界的,是一个无界缓存的等待队列。
    基于链表的阻塞队列,内部维持着一个数据缓冲队列(该队列由链表构成)。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。
    LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

    ArrayBlockingQueue 有界阻塞队列

    ArrayBlockingQueue是有界的,是一个有界缓存的等待队列。
    基于数组的阻塞队列,同LinkedBlockingQueue类似,内部维持着一个定长数据缓冲队列(该队列由数组构成)。ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
    ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue;按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea之所以没这样去做,也许是因为ArrayBlockingQueue的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。 ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。
    ArrayBlockingQueue和LinkedBlockingQueue是两个最普通、最常用的阻塞队列,一般情况下,处理多线程间的生产者消费者问题,使用这两个类足以。

    什么是Java优先级队列? 

    https://www.cnblogs.com/youruike-/articles/12054471.html

    ThreadPoolExecutor的三种队列SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue 

    https://www.cnblogs.com/feiyun126/p/7686302.html

    什么是阻塞队列?重要:

    https://www.cnblogs.com/bjxq-cs88/p/9759571.html

    阻塞队列

     优先级队列:https://blog.csdn.net/u010623927/article/details/87179364

    https://www.toutiao.com/i6821410346524213774/

     

    延迟队列:

    condition对象:https://blog.csdn.net/wit_cx/article/details/109598164

     

    展开全文
  • SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法...

    SynchronousQueue

    SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null。
    声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。公平模式和非公平模式的区别:如果采用公平模式:SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;但如果是非公平模式(SynchronousQueue默认):SynchronousQueue采用非公平锁,同时配合一个LIFO队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。

    LinkedBlockingQueue

    LinkedBlockingQueue是无界的,是一个无界缓存的等待队列。
    基于链表的阻塞队列,内部维持着一个数据缓冲队列(该队列由链表构成)。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。
    LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

    ArrayBlockingQueue

    ArrayBlockingQueue是有界的,是一个有界缓存的等待队列。
    基于数组的阻塞队列,同LinkedBlockingQueue类似,内部维持着一个定长数据缓冲队列(该队列由数组构成)。ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
    ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue;按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea之所以没这样去做,也许是因为ArrayBlockingQueue的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。 ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。
    ArrayBlockingQueue和LinkedBlockingQueue是两个最普通、最常用的阻塞队列,一般情况下,处理多线程间的生产者消费者问题,使用这两个类足以。

    转载于:https://www.cnblogs.com/feiyun126/p/7686302.html

    展开全文
  • Nim无锁队列,实现为环形缓冲区。 提供了三种实现: 是单一生产者,单一消费者有界队列。 推送和弹出无需等待。 是一个多生产者,单消费者有界队列。 弹出无需等待。 是一个多生产者,多消费者有界队列。 ...
  • 三种阻塞队列: BlockingQueue<Runnable> workQueue = null; workQueue = new ArrayBlockingQueue<>(5);//基于数组的先进先出队列,有界 workQueue = new ...//无缓冲的等待队列,无界 四...

    三种阻塞队列:
        BlockingQueue<Runnable> workQueue = null;
        workQueue = new ArrayBlockingQueue<>(5);//基于数组的先进先出队列,有界
        workQueue = new LinkedBlockingQueue<>();//基于链表的先进先出队列,无界
        workQueue = new SynchronousQueue<>();//无缓冲的等待队列,无界
    四种拒绝策略:
        RejectedExecutionHandler rejected = null;
        rejected = new ThreadPoolExecutor.AbortPolicy();//默认,队列满了丢任务抛出异常
        rejected = new ThreadPoolExecutor.DiscardPolicy();//队列满了丢任务不异常
        rejected = new ThreadPoolExecutor.DiscardOldestPolicy();//将最早进入队列的任务删,之后再尝试加入队列
        rejected = new ThreadPoolExecutor.CallerRunsPolicy();//如果添加到线程池失败,那么主线程会自己去执行该任务
    五种线程池:
        ExecutorService threadPool = null;
        threadPool = Executors.newCachedThreadPool();//有缓冲的线程池,线程数 JVM 控制
        threadPool = Executors.newFixedThreadPool(3);//固定大小的线程池
        threadPool = Executors.newScheduledThreadPool(2);
        threadPool = Executors.newSingleThreadExecutor();//单线程的线程池,只有一个线程在工作
        threadPool = new ThreadPoolExecutor();//默认线程池,可控制参数比较多   
     

    展开全文
  • Java阻塞队列使用小例

    2017-10-26 16:53:37
    SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法...
  • SynchronousQueue是一种无缓冲的等待队列,类似于无中介的直接交易,有点像原始社会中的生产者和消费者,生产者拿着产品去集市销售给产品的最终消费者,而消费者必须亲自去集市找到所要商品的直接生产者,如果一方...
  • 三种阻塞队列:    SynchronousQueue    ArrayBlockingQueue    LinkedBlockingQueue ...无缓冲无界等待队列,超出核心线程个数任务时,创建新线程执行任务...
  • 条件变量是线程之前同步的另一种机制。条件变量给多线程提供了一种会和的场所。当条件变量和互斥锁一起使用时,允许线程以竞争的方式等待特定的...基于三缓冲的队列,虽然大限度上解除了线程竞争,但是在玩家很少,消
  • 线程通信之无锁队列

    2015-12-18 16:25:46
    而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者处理能力。...
  • 条件变量是线程之前同步的另一种机制。条件变量给多线程提供了一种会和的场所。当条件变量和互斥锁一起使用时,允许线程以竞争的方式等待特定的条件...基于三缓冲的队列,虽然最大限度上解除了线程竞争,但是在玩家
  • 展示如何使用无缓冲的通道...无缓冲的通道不会有工作在队列里丢失或卡住4.创建一个工作池,比如这时候会创建出2个goroutine,被一个无缓冲通道阻塞住,等待在那里,除非通道关闭,在当前的gorotine上会无限循环读取通道...
  • SynchronousQueue没有容量,是无缓冲等待队列,是一个不存储元素阻塞队列,会直接将任务交给消费者,必须等队列中添加元素被消费后才能继续添加新元素。 拥有公平(FIFO)和非公平(LIFO)策略,非公平侧罗会...
  • 阅读文本大概需要3分钟。0x01:SynchronousQueue SynchronousQueue是无界的,是一种无缓冲的等待队列,但是...
  • SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法...
  • 消息队列

    2019-08-13 11:02:39
    削峰填谷:在突发流量时,可以通过队列缓冲,不会对后端服务产生较大压力,当峰值过去时,可以逐渐消费堆积数据,来填平流量低谷。 消息广播:一写多读 消息协议 JMS:是Java消息服务,规定了Java使用...
  • SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是isEmpty()方法...
  • 线程(四)之Queue

    2018-09-12 14:51:00
    SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是isEmpty()方法...
  • 闲谈java线程池三两事

    2020-08-21 17:31:38
    Executors线程池 三种阻塞队列 ArrayBlockingQueue<...//无缓冲的等待队列,无界 四种拒绝策略 ThreadPoolExecutor.AbortPolicy();//默认,队列满了丢任务抛出异常 ThreadPoolExecutor.DiscardPolicy();/..
  • SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是...
  •  SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()...
  •  SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()...
  • SynchronousQueue没有容量,是无缓冲等待队列,是一个不存储元素阻塞队列,会直接将任务交给消费者,必须等队列中添加元素被消费后才能继续添加新元素。 拥有公平(FIFO)和非公平(LIFO)策略 使用...
  • SynchronousQueue是无界的,是一种无缓冲的等待队列 但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加 可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法永远...

空空如也

空空如也

1 2 3 4 5
收藏数 92
精华内容 36
关键字:

无缓冲的等待队列