同步队列(Synchronous Queue)是一种特殊的队列数据结构,它具有以下特点:
同步队列的容量为0,即不能存储任何元素
。它主要用于线程间的数据传输,而不是作为一个临时数据存储的结构。同步队列的实现可以基于不同的同步原语,例如互斥锁、条件变量等。Java并发包中的SynchronousQueue就是一种常见的同步队列实现。
使用同步队列可以有效地实现线程间的同步和协作,避免了显式的锁和条件变量的使用,简化了代码的编写和维护。但需要注意合理使用同步队列,避免出现死锁和线程饥饿等问题。
总结起来,同步队列是一种阻塞的、容量为0的队列数据结构,用于实现线程间的同步和协作。
package org.Test6;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class SynchronousQueueDemo {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); //同步队列
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+" put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+" put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+" put 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T1").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}
SynchronousQueue 允许执行插入操作和删除操作的线程相互等待,因此该队列的容量为 0,即不能存储任何元素。在调用 put 方法时,如果队列中已经存在一个未被取走的元素,那么 put 操作将会阻塞直到该元素被取走
,也就是说 SynchronousQueue 的 put 方法会阻塞当前线程直到另一个线程取出元素,而 take 方法也同样如此。因此,对于上述代码,在 T1 线程中调用 put 方法时,若前一个元素还未被取出,那么会被阻塞等待,所以只能往里面放一个元素,其他两个 put 操作都会被阻塞。在 T2 线程中调用 take 方法时,如果队列中没有元素,那么线程将被阻塞直到有另一个线程插入一个元素。因此,这段代码应该只输出 Thread-1 put 1 和 T2 => 1,其他的操作都会被阻塞等待。
在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!