我不明白同步队列是如何工作的。
我理解这个想法是任务的移交是直接给线程的,但构造函数没有限制,例如像其他 API 那样的最大线程数。
因此,当 a put
oroffer
完成时,它本质上是否传递给另一个线程?
所以如果我做例如 100put
它将被传递给 100 个线程?
我试图阅读源代码,但无法弄清楚发生了什么。它似乎创建了一个节点的链接列表,其中每个节点都封装了一个线程,但是这个列表是如何维护的,例如扩展/收缩等,以及踏板如何运行任务对我来说还不清楚。
那么这个列表会随着我们提供任务而扩展吗?结果消费者线程(服务员)不断增加?
这些是否被重复使用?或者只是执行某些操作并停止?
问问题
1646 次
2 回答
4
听起来您误解了SynchronousQueue
.
SynchronousQueue
不创建任何线程。当您调用 时put
,put
直到另一个线程(您创建的线程)将该元素从SynchronousQueue
.
“如果我做例如 100 put
” 如果你有一百个线程,每个线程都调用put
相同的SynchronousQueue
,那么所有这些线程将等待直到其他线程开始将take
这些元素移开。如果你有一个线程,它一次只会做一个put
,并且每次它都会等待另一个线程在添加另一个之前获取该元素。
内部使用的列表是一个链表,它像链表一样扩展并获得 GC 处理。
于 2013-08-27T21:07:19.547 回答
2
我理解这个想法是任务的移交是直接给线程的,但是构造函数没有限制,例如像其他 API 那样的最大线程数。
队列实现的构造函数中的所有 int 参数中的第一个SIZE
是线程数,而不是线程数。
那么这个列表会随着我们提供任务而扩展吗?结果消费者线程(服务员)不断增加?
同步队列用于切换目的。来自生产者的put()
调用将阻塞,直到队列中有一个消费者take()
。这与线程数无关。消费者线程不一定要增加。一旦消费者完成处理一条消息,它就可以再次从队列中执行 take()。
public class MyWorker extends Thread {
private final BlockingQueue<String> queue;
public MyWorker(BlockingQueue<String> queue) {
this.queue = queue;
}
public void run() {
try {
while ( true ) {
String s = queue.take();
doWork(s);
}
}
catch ( InterruptedException ie ) {
// just terminate
}
}
}
public class SyncQueueExample {
// …
public SyncQueueExample() {
try {
int workItem = 0;
// Create a synchronous queue
BlockingQueue<String> queue = new SynchronousQueue<String>();
// Create the child worker thread
MyWorker worker = new MyWorker(queue);
worker.start();
// Start sending to the queue
while ( true ) {
System.out.println("\nPlacing work on queue");
String work = "Work Item:" + (++workItem);
queue.put(work);
}
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
输出:运行时,队列生产者和消费者之间的输出将是“协调的”,实际上并交替如下:
Placing work on queue
Thread 'Thread-1' processing work: Work Item:1
Placing work on queue
Thread 'Thread-1' processing work: Work Item:2
Placing work on queue
Thread 'Thread-1' processing work: Work Item:3
Placing work on queue
Thread 'Thread-1' processing work: Work Item:4
更多关于同步队列
于 2013-08-27T21:08:05.360 回答