SynchronousQueue 与 BlockingQueue

SynchronousQueue 与 BlockingQueue

package pkg;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;



public class QueueTest {
    public static void main(String[] args) {
        BlockingQueue<String> blockQueue = new LinkedBlockingQueue<String>();//new SynchronousQueue<String>()
        class QueuePuter implements Runnable{
            private BlockingQueue queue;
            public QueuePuter(BlockingQueue queue) {
                this.queue = queue;
            }
            
            public void run() {
                try {
                    for(int i=0;i<10;i++){
                        queue.put("Item "+i);
                        System.out.println("Put  >>> Item "+i);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        class QueueTaker implements Runnable{
            private BlockingQueue queue;
            public QueueTaker(BlockingQueue queue) {
                this.queue = queue;
            }
            public void run() {
                try {
                    Object obj = null;
                    while((obj = queue.take())!=null){
                        System.out.println("Take >>> "+obj);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        new Thread(new QueueTaker(blockQueue)).start(); 
        //如果是 SynchronousQueue 把这行注释掉 程序会阻塞,说明如果没有线程执行take()操作则所有线程的put()操作都会被阻塞。
        //如果是 LinkedBlockingQueue 把这行注释掉 程序会正常退出,说明就算没有take()操作的线程,所有线程的put()操作也可以把所有数据写入管道,而且管道容量可以不限。
        

        
        new Thread(new QueuePuter(blockQueue)).start();
        //如果是 SynchronousQueue 把这行注释掉 程序会阻塞, 说明如果没有线程执行put()操作则所有线程take()都会被阻塞。而且take()操作执行了几次,put()操作也只能执行几次,说明管道是没有容量的,同时只能操作一个元素。
        //如果是 LinkedBlockingQueue 把这行注释掉 程序会阻塞, 说明如果管道是空的并且没有线程执行put()操作则所有线程take()都会被阻塞。
        
    }
}

  注意2 :它是线程安全的,是阻塞的。
  注意3 :不允许使用 null 元素。
  注意4 :公平排序策略是指调用put的线程之间,或take的线程之间。
 公平排序策略可以查考ArrayBlockingQueue中的公平策略。
  注意5 :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。

你可能感兴趣的:(java,SynchronousQueu)