我想知道如何处理以下情况:
当生产者醒来并开始将元素放入队列(仅从列表中传输对象)时,让我们一次假设100个元素,消费者将立即唤醒,在生产者将100个元素放入队列之前清空队列元素?
还是我可以期望消耗线程的休眠时间更长?
答案 0 :(得分:0)
LinkedBlockingQueue对其所有操作都使用单锁(ReentrantLock)。
在您的情况下,如果您一次说100个元素,则意味着调用put方法100次。 put方法尝试在插入之前先获取锁。因此,很有可能给消费者线程一个机会,并且可能耗尽队列。
LBQ还使用非公平锁定,因此很可能发生饥饿。
答案 1 :(得分:0)
感谢@Neerav 我做了一点测试
private static void raceforIntegers() {
BlockingDeque<Integer> q = new LinkedBlockingDeque<>();
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
// Delay producer 1 sec, so consumer always waits at 1st
ex.scheduleAtFixedRate(() -> {
if (q.isEmpty()) {
Stream.iterate(0, i -> ++i)
.limit(10)
.forEach(q::add);
} else {
ex.shutdown();
}
}, 1L, 1L, TimeUnit.SECONDS);
consumeIntegers(q);
}
private static void consumeIntegers(BlockingDeque<Integer> q) {
int elememts = 30;
StringBuilder sb = new StringBuilder();
do {
try {
int n = q.take();
int s = q.size();
sb.append(s + ":::::" + n + "\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (elememts-- > 0);
System.out.println(sb);
}
输出
Size Num
1:::::0
8:::::1
7:::::2
6:::::3
5:::::4
4:::::5
3:::::6
2:::::7
1:::::8
0:::::9
5:::::0
8:::::1
7:::::2
6:::::3
5:::::4
4:::::5
3:::::6
2:::::7
1:::::8
0:::::9
3:::::0
7:::::1
7:::::2
6:::::3
5:::::4
4:::::5
3:::::6
2:::::7
1:::::8
0:::::9
9:::::0