同步队列是一个没有一个数据缓冲的阻塞队列,在同步队列上的插入操作必须等待相应的删除执行完成才能执行,反之亦然。
不能调用peek方法来查看队列中是否有数据元素,也不允许对整个队列进行迭代遍历。
类 SynchronousQueue 是java集合框架中的一员,该类的定义的形式如下。
public class SynchronousQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>,Serializable
其中,E指明同步队列中的元素类型。
该类定义了以下两个构造方法。
1)public SynchronousQueue( )
2) public SynchronousQueue( boolean fair ) //使用公平策略创建同步队列。
SynchronousQueue类的常用方法,如下:
int drainTo(Collection<? super E> c) 移除队列中的所有可用的元素,并将他们添加到集合之中。
int drainTo(Collection<? super E> c, int maxElements ) 最多从此队列移除给定数量的可用元素,并将这些元素添加到集合中。
boolean offer(E e) 如果另一个线程正在等待以便接收指定元素,则将指定的元素插入到此队列中。
boolean offer(E o,long timeOut,TimeUnit unit) 将指定的元素插入到此队列,如有必要等待则等待指定的时间,以便另一个线程接收它。
E pull() 如果另一个线程当前正要使用某个元素,则获取并转移到此队列的头
E poll(long timeout,TimeUnit unit) 获取并移除此队列的头,如有必要则等待指定的时间,以便另一个线程插入它。
void put(E 0) 将指定的元素o 添加到此队列,如有必要怎等待另一个线程接受它。
E take() 获取并移除此队列的头,如果有必要等待则等待另一个线程插入它
demo 示例:
使用同步队列 实现生产消费问题。
//生产者
public class Producer extends Thread{
SynchronousQueue<Integer> queue;
Producer( SynchronousQueue queue){
this.queue = queue;
}
public void run(){
for(int i=0;i<5;i++){
int data = (int)(Math.random()*100);
System.out.println("生产者生产了一个数据:"+data);
//将数据放进队列
try{
queue.put(data);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//消费者类
public class Conusumer extends Thread{
SynchronousQueue<Integer> queue;
Consumer(SynchronousQueue queue){
this.queue = queue;
}
//消费数据 取数据
public void run(){
for(int i=0;i<5;i++){
try{
System.out.println("消费者消费了一个数据::" + queue.take() );
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//启动类
public class Index{
public static void main(String [] args){
SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>();
Thread producer = new Producer(queue);
Thread consumer = new Consumer(queue);
producer.start();
consumer.start();
}
}
//运行结果:
生产者生产了一个数据:38
生产者生产了一个数据:26
消费者消费了一个数据::38
消费者消费了一个数据::26
生产者生产了一个数据:6
消费者消费了一个数据::6
......