![](/img/trans.png)
[英]How to create Java concurrent queue from which we can blocking-take more than 1 element in single call?
[英]Blocking queue not working in java, I can put more element than the defined size of blocking queue
我已经声明了一个大小为 1 的 BlockingQueue
final BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(1);
.
但我可以在队列中添加超过 1 个元素。 我确信我在这方面遗漏了一些东西,这是 BlockingQueue 的核心属性。 这是 java 文档中的代码。
/**
* Creates an {@code ArrayBlockingQueue} with the given (fixed)
* capacity and default access policy.
*
* @param capacity the capacity of this queue
* @throws IllegalArgumentException if {@code capacity < 1}
*/
public ArrayBlockingQueue(int capacity) {
this(capacity, false);
}
但是当我实现时,我能够产生超过 1 个元素,根据我的说法,如果 BlockingQueue 的大小为 1,那么在产生 1 个元素之后,它应该等待消费者使用该元素。 这是代码和代码的output。
我需要一个解释,请你帮我解决这个问题。
我试过谷歌搜索和 StackOverflow 都没有成功。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BlockingQueueTestWorking {
public static void main(String[] args) {
final BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(1);
Runnable producer = () -> {
try {
int iterator = 0;
while (true) {
if (iterator++ == 10)
break;
String name = Thread.currentThread().getName();
Integer i = (int) (Math.random() * 10);
blockingQueue.put(i);
System.out.println(name + " Producing:-> " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable consumer = () -> {
try {
int iterator = 0;
while (true) {
if (iterator++ == 10)
break;
String name = Thread.currentThread().getName();
Integer take = blockingQueue.take();
System.out.println(name + " Consuming:<- " + take);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread threadProducer = new Thread(producer);
final ExecutorService executor = Executors.newFixedThreadPool(10);
executor.execute(threadProducer);
Thread threadConsumer = new Thread(consumer);
executor.execute(threadConsumer);
executor.shutdown();
}
}
Output:
pool-1-thread-1 Producing:-> 2
pool-1-thread-1 Producing:-> 7
pool-1-thread-2 Consuming:<- 2
pool-1-thread-2 Consuming:<- 7
pool-1-thread-1 Producing:-> 6
pool-1-thread-2 Consuming:<- 6
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 6
pool-1-thread-2 Consuming:<- 6
pool-1-thread-1 Producing:-> 1
pool-1-thread-2 Consuming:<- 1
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 4
pool-1-thread-2 Consuming:<- 4
将打印更改为
System.out.println(String.format("[%s]", new Timestamp(System.currentTimeMillis())) + " Producing:-> " + i);
和
System.out.println(String.format("[%s]", new Timestamp(System.currentTimeMillis())) + name + " Consuming:<- " + take);
你会看到它们实际上没有按正确的时间顺序打印
这只是两个线程之间的竞争条件。
您相信它产生了第二条消息,因为您在消费者之前看到了生产者的 output 。 很幸运,他的System.out
在消费者的处理之前得到了处理。
尝试调试它,你会看到没有添加第二个元素,而消费者之前没有阅读第一个元素。 不要相信控制台输出中的顺序......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.