美文网首页
使用SynchronousQueue

使用SynchronousQueue

作者: M_lear | 来源:发表于2022-08-03 16:06 被阅读0次

最近需要实现这样一个接口:
每次调用接口,触发一个线程生产一个对象,然后当前线程消费这个对象返回。

可以使用AtomicReference和CountDownLatch实现

public class Main {
    public static void main(String[] args) throws InterruptedException {
        AtomicReference<String> msg = new AtomicReference<>();
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            try {
                // 模拟耗时操作
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            msg.set("abc");
            countDownLatch.countDown();
        }).start();
        countDownLatch.await(10, TimeUnit.SECONDS);
        System.out.println(msg.get());
    }
}

使用SynchronousQueue

public class Main {
    public static void main(String[] args) throws InterruptedException {
        SynchronousQueue<String> queue = new SynchronousQueue<>();
        new Thread(() -> {
            try {
                // 模拟耗时操作
                TimeUnit.SECONDS.sleep(5);
                queue.offer("abc", 10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println(queue.poll(10, TimeUnit.SECONDS));
    }
}

SynchronousQueue是一种容量为0的阻塞队列,其size方法固定返回0。

    public int size() {
        return 0;
    }

虽然内部没有暂存生产者生产的对象的容器,但却有线程的容器。所以依然允许多个线程同时put和take。

提供了6个存取方法,它们的区别如下表所示:

void put(E e):如果e没被其他线程消费,就一直阻塞 E take():如果没有其他线程来存,就一直阻塞
boolean offer(E e):立即返回不会阻塞,如果offer之前已有其他线程等着别人来存,则插入成功返回true,否则返回false E poll():立即返回不会阻塞,如果poll之前已有其他线程等着别人来取,则返回取得的元素,否则返回null
boolean offer(E e, long timeout, TimeUnit unit):限时等待,如果在此期间有其他线程来取,则插入成功返回true,否则返回false E poll(long timeout, TimeUnit unit):限时等待,如果在此期间有其他线程来存,则返回取得的元素,否则返回null

相关文章

网友评论

      本文标题:使用SynchronousQueue

      本文链接:https://www.haomeiwen.com/subject/jenswrtx.html