Synchronousqueue学习

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进去的值。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值