Threadpoolexecutor commits a task under a certain queue if the execution queue full must be blocked by a workaround __java

Source: Internet
Author: User
Original: http://stackoverflow.com/questions/4521983/ java-executorservice-that-blocks-on-submission-after-a-certain-queue-size/4522411#4522411

Problem:

Need to solve only one IO read and write producer's task parallelization, each consumer data in memory, want to control the number of consumers waiting. Threadpoolexecutor class with Java

Workaround 1: Implement a queue, and the Offer method is also blocked

Disadvantage: Changed the original intention of the Threadpoolexecutor, because the task is to block the way, then reach the maximumpoolsize after the thread, because the method of the offer is blocked, can not take the idle thread back

public class Limitedqueue < E > extends Linkedblockingqueue < e > {public limitedqueue (int maxSize) {super ( MaxSize); @Override public Boolean offer (e e) {//Turn offer () and add () to a blocking calls (unless interrupted) try {put (e); return true; catch (Interruptedexception IE) {thread.currentthread (). interrupt ();} return false; } }

Workaround 2: Use Rejectedexecutionhandler, Method 1

The code for Threadpoolexecutor.execute (Runnable) is as follows

if (IsRunning (c) && workqueue.offer (command)) {int recheck = ctl. get (); if (! isrunning (recheck) && re Move (command)) reject (command); else if (workercountof (recheck) = = 0) Addworker (null, FALSE); else if (! Addworker (command, False)) reject (command);

An offer block causes else if (!addworker (command, False)) to be inaccessible, using the Rejectedexecutionhandler
public void Rejectedexecution (Runnable R, Threadpoolexecutor executor) {try {if (! Executor.isshutdown ()) {executor.ge Tqueue (). put (R); } catch (Interruptedexception e) {thread.currentthread (). interrupt (); throw new Rejectedexecutionexception ("Executor is interrupted while the task is waiting to put on work queue, E);}

Description: Corepoolsize==0 can lead to problems, put methods lead to inconsistent threadpoolexecutor packaging, and have an impact, corepoolsize < maxpoolsize is usually useful in this way.

Workaround 3: Subclass Threadpoolexecutor, before and after submission, using semaphores to limit

public class Boundedexecutor extends threadpoolexecutor{private final semaphore semaphore, public boundedexecutor (int bo und) {Super (bound, Integer.max_value, 60L, Timeunit.seconds, new Synchronousqueue < Runnable > ()); semaphore = NE W Semaphore (bound); }/* *submits task to execution pool, but blocks while number of running threads * has reached the bound limit/public & Lt T > Future < T > submitbutblockiffull (Final callable < T > Task) throws interruptedexception{Semaphore.acq Uire (); return submit (Task); @Override protected void AfterExecute (Runnable R, Throwable t) {Super.afterexecute (r, T); Semaphore.release ();}

Method 4: Use the lock and condition variable in Threadpoolexecutor's Beforeexecute/afterexecute fuss

Import Java.util.concurrent.BlockingQueue; Import Java.util.concurrent.ThreadPoolExecutor; Import Java.util.concurrent.TimeUnit; Import java.util.concurrent.locks.Condition; Import Java.util.concurrent.locks.ReentrantLock; * * * Blocks Current task execution if there isn't enough resources for it. * Maximum Task Count usage controlled by Maxtaskcount. * * public class Blockingthreadpoolexecutor extends Threadpoolexecutor {private final Reentrantlock Tasklock = new Reentra NTLock (); Private final Condition unpaused = Tasklock.newcondition (); private final int maxtaskcount; private volatile int currenttaskcount; Public blockingthreadpoolexecutor (int corepoolsize, int maximumpoolsize, long keepalivetime, Timeunit unit, Blockingqueue < Runnable > workqueue, int maxtaskcount) {super (corepoolsize, Maximumpoolsize, KeepAliveTime, Unit, Workqueue); this. Maxtaskcount = Maxtaskcount; }/* * Executes task if there is enough system resources for it. otherwise * waits. * * @OveRride protected void BeforeExecute (Thread T, Runnable R) {Super.beforeexecute (T, r); Tasklock. Lock (); try {//Spin WHI Le we won't have enough capacity for this job while (Maxtaskcount < Currenttaskcount) {try {unpaused.await ();} CA TCH (interruptedexception e) {t.interrupt ();}} Currenttaskcount + +; finally {Tasklock.unlock ();}} * * * Signalling that one more task is welcome */@Override protected void AfterExecute (Runnable R, Throwable t) {super. AfterExecute (r, T); Tasklock. Lock (); try {currenttaskcount-; Unpaused.signalall ();} finally {Tasklock.unlock ()}} }

Workaround 5: This method is not universal, set to a blocking queue with fixed length future, consumer consumption blocking the future in the queue, the producer submits the task by put to the blocking queue for processing

Final Executorservice executor = Executors.newfixedthreadpool (numworkerthreads); Final Linkedblockingqueue < Future > futures = new linkedblockingqueue <> (maxqueuesize); try {thread taskgenerator = new Thread () {@Override public void run () {while (Reader.hasnext) {Callable task = Generat ETask (Reader.next ()); Future Future = executor.submit (Task); try {//If queue is full blocks until a task/are completed and hence no future tasks are submitted. Futures.put (Compoun Dfuture); The catch (Interruptedexception ex) {Thread.CurrentThread (). interrupt ();}} Executor.shutdown (); } taskgenerator.start (); Read from queue as long as task are being generated//while queue has elements in it (taskgenerator.isalive) || ! Futures.isempty ()) {Future compoundfuture = Futures.take ();//Do Something} catch (Interruptedexception ex) {Thread. CurrentThread (). interrupt (); The catch (Executionexception ex) {throw new MyException (ex);} finally {Executor.shutdownnow ();}

other documents available for reference http://howtodoinjava.com/core-java/multi-threading/ how-to-use-blockingqueue-and-threadpoolexecutor-in-java/
Http://stackoverflow.com/questions/7556465/why-threadpoolexecutor-has-blockingqueue-as-its-argument
Http://stackoverflow.com/questions/3446011/threadpoolexecutor-block-when-queue-is-full
http://stackoverflow.com/questions/2001086/ how-to-make-threadpoolexecutors-submit-method-block-if-it-is-saturated/2001205#2001205
http://stackoverflow.com/questions/2001086/how-to-make-threadpoolexecutors-submit-method-block-if-it-is-saturated

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.