首页 文章

同步队列是否在每个offer / put上创建一个线程?

提问于
浏览
1

我无法理解Synchronous Queue是如何工作的 .
我理解这个想法是任务的切换是直接到线程但是构造函数没有像其他API那样绑定的最大线程数 .
所以当 putoffer 完成时,它实际上是否传递给另一个线程?
如果我这样做,例如100 put 它将传递给100个线程?
我试图阅读源代码,但无法弄清楚会发生什么 . 它似乎创建了一个链接的节点列表,其中每个节点封装一个线程,但是如何保持这个列表,例如扩展/收缩等以及踏板如何运行任务对我来说并不清楚 .
因此,当我们提供任务时,此列表会扩展吗?结果消费者线程(服务员)不断增加?
这些都重复使用了吗?或者只是执行一些并停止?

2 回答

  • 2

    听起来你误解了 SynchronousQueue 的目的 .

    SynchronousQueue 不会创建任何线程 . 当你调用 put 时, put 没有完成,直到另一个线程(你创建的一个线程)从 SynchronousQueue 中取出该元素 .

    “如果我做了例如100 put ”如果你有一百个线程,每个线程在同一个 SynchronousQueue 上调用 put ,那么所有这些线程将等待,直到其他线程开始 take 这些元素消失 . 如果你有一个线程,它一次只能执行一个 put ,并且每次在添加另一个线程之前等待另一个线程获取该元素 .

    内部使用的列表是一个链表,它会像链接列表一样扩展并获得GC .

  • 4

    我理解这个想法是任务的切换是直接到线程的,但是构造函数没有像其他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();
            }
        }
    }
    

    Output: 运行时,队列生成器和使用者之间的输出将有效"coordinated,",并按此替换:

    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
    

    更多关于Synchronous Queue

相关问题