JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别

JDK7对JDK5中的J.U.C并发工具进行了增强,其中之一就是新增了TransferQueue。

public interface TransferQueue extends BlockingQueue

从类的源码可以看到TransferQueue同时也是一个阻塞队列,它具备阻塞队列的所有特性,主要介绍下上面5个新增API的作用。

1.transfer(E e)若当前存在一个正在等待获取的消费者线程,即立刻将e移交之;否则将元素e插入到队列尾部,并且当前线程进入阻塞状态,直到有消费者线程取走该元素。

[java]  view plain  copy
  1. public class TransferQueueDemo {  
  2.   
  3.     private static TransferQueue queue = new LinkedTransferQueue();  
  4.   
  5.     public static void main(String[] args) throws Exception {  
  6.   
  7.         new Productor(1).start();  
  8.   
  9.         Thread.sleep(100);  
  10.   
  11.         System.out.println("over.size=" + queue.size());  
  12.     }  
  13.   
  14.     static class Productor extends Thread {  
  15.         private int id;  
  16.   
  17.         public Productor(int id) {  
  18.             this.id = id;  
  19.         }  
  20.   
  21.         @Override  
  22.         public void run() {  
  23.             try {  
  24.                 String result = "id=" + this.id;  
  25.                 System.out.println("begin to produce." + result);  
  26.                 queue.transfer(result);  
  27.                 System.out.println("success to produce." + result);  
  28.             } catch (InterruptedException e) {  
  29.                 e.printStackTrace();  
  30.             }  
  31.         }  
  32.     }  
  33. }  
可以看到生产者线程会阻塞,因为调用transfer()的时候并没有消费者在等待获取数据。队列长度变成了1,说明元素e没有移交成功的时候,会被插入到阻塞队列的尾部。

2.tryTransfer(E e)若当前存在一个正在等待获取的消费者线程,则该方法会即刻转移e,并返回true;若不存在则返回false,但是并不会将e插入到队列中。这个方法不会阻塞当前线程,要么快速返回true,要么快速返回false。

3.hasWaitingConsumer()和getWaitingConsumerCount()用来判断当前正在等待消费的消费者线程个数。


4.tryTransfer(E e, long timeout, TimeUnit unit) 若当前存在一个正在等待获取的消费者线程,会立即传输给它; 否则将元素e插入到队列尾部,并且等待被消费者线程获取消费掉。若在指定的时间内元素e无法被消费者线程获取,则返回false,同时该元素从队列中移除。

[java]  view plain  copy
  1. public class TransferQueueDemo {  
  2.   
  3.     private static TransferQueue queue = new LinkedTransferQueue();  
  4.   
  5.     public static void main(String[] args) throws Exception {  
  6.   
  7.         new Productor(1).start();  
  8.   
  9.         Thread.sleep(100);  
  10.   
  11.         System.out.println("over.size=" + queue.size());//1  
  12.           
  13.         Thread.sleep(1500);  
  14.   
  15.         System.out.println("over.size=" + queue.size());//0  
  16.     }  
  17.   
  18.     static class Productor extends Thread {  
  19.         private int id;  
  20.   
  21.         public Productor(int id) {  
  22.             this.id = id;  
  23.         }  
  24.   
  25.         @Override  
  26.         public void run() {  
  27.             try {  
  28.                 String result = "id=" + this.id;  
  29.                 System.out.println("begin to produce." + result);  
  30.                 queue.tryTransfer(result, 1, TimeUnit.SECONDS);  
  31.                 System.out.println("success to produce." + result);  
  32.             } catch (Exception e) {  
  33.                 e.printStackTrace();  
  34.             }  
  35.         }  
  36.     }  
  37. }  
第一次还没到指定的时间,元素被插入到队列中了,所有队列长度是1;第二次指定的时间片耗尽,元素从队列中移除了,所以队列长度是0。


你可能感兴趣的:(Thread)