最近需要实现这样一个接口:
每次调用接口,触发一个线程生产一个对象,然后当前线程消费这个对象返回。
可以使用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 |
网友评论