Java – ThreadPoolExecutor and queue

I think with ThreadPoolExecutor, we can submit runnables for execution in the BlockingQueue passed in the constructor or use the execute method

public class MyThreadPoolExecutor {  

    private static ThreadPoolExecutor executor;  

    public MyThreadPoolExecutor(int min,int max,int idleTime,BlockingQueue<Runnable> queue){  
        executor = new ThreadPoolExecutor(min,max,10,TimeUnit.MINUTES,queue);   
        //executor.prestartAllCoreThreads();  
    }  

    public static void main(String[] main){
        BlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
        final String[] names = {"A","B","C","D","E","F"};  
        for(int i = 0; i < names.length; i++){  
            final int j = i;  
            q.add(new Runnable() {  

                @Override  
                public void run() {  
                    System.out.println("Hi "+ names[j]);  

                }  
            });         
        }  
        new MyThreadPoolExecutor(10,20,1,q);   
        try {  
            TimeUnit.SECONDS.sleep(5);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        /*executor.execute(new Runnable() {  

            @Override  
            public void run() {  

                System.out.println("++++++++++++++");  

            }   
        });  */
        for(int i = 0; i < 100; i++){  
            final int j = i;  
            q.add(new Runnable() {   

                @Override  
                public void run() {  
                    System.out.println("Hi "+ j);  

                }  
            });  
        }   


    }  


}

Unless I uncomment executor prestartAllCoreThreads(); Otherwise, this code does nothing In the constructor or I call runnable's execution to print system out. println(“”); (it was also commented out)

Why? Quote (my focus):

OK So my queue is not empty But I created the executor, I slept, and then I added the new runnables to the queue (100 in the loop) When a new task comes, doesn't this cycle count? Why doesn't it work and I have to pre start or explicitly call execution?

Solution

When the execution task arrives, worker threads will be generated, which are threads interacting with the underlying work queue If you start with a non empty work queue, you need to pre start the work program See implementation in openjdk 7

I repeat, workers are workers who interact with work queues They are generated on demand only when passed through execute (or the layers above it, such as invokeall, submit, etc.) if they are not started, the workload you add to the queue is not important, because it is not checked without any staff starting

ThreadPoolExecutor does not generate worker threads before necessary, or if you preempt their creation through the methods prestartallcorethreads and prestartcorethread If no worker is started, no work in your queue can be completed

The reason for adding initial execution is that it forces the creation of a unique core worker thread that can then begin processing work in the queue You can also call prestartcorethread and receive similar behavior If you want to start all working programs, you must call prestartallcorethreads or submit this number of tasks through execute

Refer to the execution code below

/**
 * Executes the given task sometime in the future.  The task
 * may execute in a new thread or in an existing pooled thread.
 *
 * If the task cannot be submitted for execution,either because this
 * executor has been shutdown or because its capacity has been reached,* the task is handled by the current {@code RejectedExecutionHandler}.
 *
 * @param command the task to execute
 * @throws RejectedExecutionException at discretion of
 *         {@code RejectedExecutionHandler},if the task
 *         cannot be accepted for execution
 * @throws NullPointerException if {@code command} is null
 */
public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running,try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount,and so prevents false alarms that would add
     * threads when it shouldn't,by returning false.
     *
     * 2. If a task can be successfully queued,then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped,or start a new thread if there are none.
     *
     * 3. If we cannot queue task,then we try to add a new
     * thread.  If it fails,we kNow we are shut down or saturated
     * and so reject the task.
     */
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command,true))
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null,false);
    }
    else if (!addWorker(command,false))
        reject(command);
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>