java - Why is BlockingQueue.take() not releasing the thread? -


in simple short program, notice program hangs forever because take() not release thread. according understanding, take() causes thread released though task blocked on take().

edited:

this works (thanks fixing autoboxing):

import java.util.arraylist; import java.util.collection; import java.util.concurrent.callable; import java.util.concurrent.executionexception; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.future; import java.util.concurrent.linkedblockingqueue;  public class producersconsumers {     private static int thread_count = 5;      public static void main(string[] args) throws executionexception, interruptedexception {         final executorservice executorpool = executors.newfixedthreadpool(thread_count);         final linkedblockingqueue<long> queue = new linkedblockingqueue<long>();          collection<future<long>> collection = new arraylist<future<long>>();           // producer:         (int = 0; < 20; i++) {             collection.add(executorpool.submit(new callable<long>() {                 @override                 public long call() throws exception {                     (int = 100; >= 0; i--) {                         queue.put((long) i);                     }                     return -1l;                 }             }));         }          // consumer:         (int = 0; < 20; i++) {             collection.add(executorpool.submit(new callable<long>() {                 @override                 public long call() throws exception {                     while (true) {                         long item = queue.take();                         if (item.intvalue() == 0) {                             break;                         }                     }                     return 1l;                 }             }));         }          long sum = 0;         (future<long> item : collection) {             sum += item.get();         }          executorpool.shutdown();         system.out.println("sum = " + sum);     } } 

but if swap producer , consumer invocations, hang:

import java.util.arraylist; import java.util.collection; import java.util.concurrent.callable; import java.util.concurrent.executionexception; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.future; import java.util.concurrent.linkedblockingqueue;  public class producersconsumers {     private static int thread_count = 5;      public static void main(string[] args) throws executionexception, interruptedexception {         final executorservice executorpool = executors.newfixedthreadpool(thread_count);         final linkedblockingqueue<long> queue = new linkedblockingqueue<long>();          collection<future<long>> collection = new arraylist<future<long>>();           // consumer:         (int = 0; < 20; i++) {             collection.add(executorpool.submit(new callable<long>() {                 @override                 public long call() throws exception {                     while (true) {                         long item = queue.take();                         if (item.intvalue() == 0) {                             break;                         }                     }                     return 1l;                 }             }));         }          // producer:         (int = 0; < 20; i++) {             collection.add(executorpool.submit(new callable<long>() {                 @override                 public long call() throws exception {                     (int = 100; >= 0; i--) {                         queue.put((long) i);                     }                     return -1l;                 }             }));         }          long sum = 0;         (future<long> item : collection) {             sum += item.get();         }          executorpool.shutdown();         system.out.println("sum = " + sum);     } } 

to understanding producer , consumer order should not matter. in other words, there notion of task , thread. thread independent of code program whereas task associated program. therefore, in example, when jvm assigns thread execute of callable tasks, if consumer instantiated first, task block on take(). once jvm discovers task blocked, release thread (or understand not releasing it) , places worker thread pool in preparation processing runnable task (which in case producers). consequently, @ end of instantiating callable's, there should 40 tasks 5 threads; 20 of tasks blocked, 5 of tasks should running , 15 should waiting (to run).

i think misunderstand how threads , threadpools work. threadpool typically has work item queue contains items worked on (in case callable<>s).

it contains (maximum) number of threads (in case 5) can work on items.

the lifetime of active thread defined code executes - method. thread becomes "alive" when starts executing method , ends when returns. if method blocks wait on signal not mean the thread can go away , execute other method - that's not how threads work. instead thread blocked until can continue execution , enable other threads run.

the method run threadpool thread looks this:

void threadloop() {     while (!quit)     {         callable<t> item = null;         synchronized (workqueue)         {             if (workqueue.count == 0)                 workqueue.wait();              // have been woken other reason check again             if (workqueue.count > 0)                 item = workqueue.pop();         }         if (item != null)              item.call();     } } 

this more or less pseudo code (i'm not java developer) should show concept. item.call() executes method supplied user of pool. if method blocks, happens? - thread blocked in execution of item.call() until method wakes again. can't go away , execute other code arbitrarily.


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -