c语言编程笔录

首页 >   > 笔记大全

笔记大全

SynchronousQueue同步器怎么在java项目中使用

更新时间:2023-10-25

什么是SynchronousQueue?

SynchronousQueue是一种线程同步的队列,它的特点是它的put操作和take操作是在不同的线程中进行的,当一个线程调用put方法时,它会阻塞直到另一个线程调用take方法取走该元素,反之亦然。SynchronousQueue本身不存储元素,因此在使用它时需要注意它的容量始终为0。

public class SynchronousQueue extends AbstractQueue
        implements BlockingQueue, java.io.Serializable {
    //...
}

SynchronousQueue的使用场景

SynchronousQueue最常用的场景就是线程间传递消息或者事件,比如一个线程生成事件,而另一个线程需要处理这个事件,此时可以使用SynchronousQueue来实现这个线程之间的同步。它也可以用来限制并发执行的线程数量,通过将容量设置为1,每次只有一个线程能够执行。

示例1:使用SynchronousQueue实现线程间数据交换

下面是一个简单的使用SynchronousQueue实现线程间数据交换的示例代码:

import java.util.concurrent.SynchronousQueue;

public class SynchronousQueueExample {
    public static void main(String[] args) {
        final SynchronousQueue queue = new SynchronousQueue<>();

        new Thread(() -> {
            try {
                int data = queue.take();
                System.out.println("取出数据:" + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            int data = 1;
            try {
                queue.put(data);
                System.out.println("加入数据:" + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

在这个示例中我们创建了两个线程,一个线程调用了take方法来取走数据,另一个线程调用了put方法来向队列中添加数据。需要注意的是,这两个线程是在不同的线程中运行的,因此线程的执行是互不影响的。

示例2:使用SynchronousQueue限制并发执行线程数量

SynchronousQueue也可以用来限制并发执行的线程数量,下面是一个示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;

public class SynchronousQueueExample {
    public static void main(String[] args) {
        final SynchronousQueue queue = new SynchronousQueue<>();
        ExecutorService executor = Executors.newFixedThreadPool(3);

        for (int i = 1; i <= 5; i++) {
            executor.submit(() -> {
                int data = (int) (Math.random() * 100);
                try {
                    queue.put(data);
                    System.out.println(Thread.currentThread().getName() + " 加入数据:" + data);
                    Thread.sleep(1000);
                    int result = queue.take();
                    System.out.println(Thread.currentThread().getName() + " 取出数据:" + result);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
    }
}

在这个示例中,我们创建了一个线程池,其中最多只能有3个线程同时运行,通过SynchronousQueue的put和take方法,我们限制了同时被执行的线程数量,确保了并发线程的数量不会超过3个。