SychronousQueue
源码注释
* A {@linkplain BlockingQueue blocking queue} in which each insert
* operation must wait for a corresponding remove operation by another
* thread, and vice versa. A synchronous queue does not have any
* internal capacity, not even a capacity of one.
1、特点
1:插入操作必须等待另一个线程的的删除,删除操作必须等待另一个线程的插入操作
如put插入然后等待另一个线程的take或poll take 移除元素等待等待另一个线程put或add操作,等到对应操作后实现transfer,传给相应的消费者
2:容量为0,并没有任何元素插入到队列当中
2、代码
package com.test.luo.thread;
import java.util.concurrent.SynchronousQueue;
/**
* Synchronousqueue使用测试类
*
*
*/
public class SynchronousQueueTest{
static SynchronousQueue<String> synQueue = new SynchronousQueue<String>();
volatile String c = null;
class SynQ implements Runnable{
int flag =0;
public SynQ(int flag) {
// TODO Auto-generated constructor stub
this.flag = flag;
}
@Override
public void run() {
if(flag==0){
try {
System.out.println("flag==0 start "+System.currentTimeMillis());
//Retrieves and removes the head of this queue, waiting if necessary
//for another thread to insert it.
//提取且删除队列的头部元素,等待其他线程的插入操作
c = synQueue.take();
System.out.println("flag==0 end "+System.currentTimeMillis());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
System.out.println("flag==1 wait start "+System.currentTimeMillis());
Thread.sleep(20000);
System.out.println("flag==1 wait end "+System.currentTimeMillis());
synQueue.add(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
}
}
}
//启动两个线程t1负责从synchronousqueue中take元素
//t2负责add元素
public static void main(String [] args){
SynchronousQueueTest test = new SynchronousQueueTest();
Thread t1 = new Thread(test.new SynQ(0),"t1");
Thread t2 = new Thread(test.new SynQ(1),"t2");
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(test.c);
}
}
3、输入结果
flag==1 wait start 1550943259761
flag==0 start 1550943259761
flag==1 wait end 1550943279762
flag==0 end 1550943279762
t2
4、程序分析
1).启动两个线程t1负责从synchronousqueue中take元素,t2先休眠一段时间,然后进行add操作。
2).当出现flag==0 start 1550943259761(即执行了take操作后),通过查看后台线程状态(parking,因为使用了Locksupport)可以看出t1一直在等来其他线程的插入操作来完成take操作(jps -lvm取到进程pid 然后jstack -l pid即可)。
3). 待t1执行了add操作后,t2也完成了take操作,而且c的值为t1add进去的值。