Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ThreadPoolExecutor和队列_Java_Multithreading_Concurrency_Java.util.concurrent_Threadpoolexecutor - Fatal编程技术网

Java ThreadPoolExecutor和队列

Java ThreadPoolExecutor和队列,java,multithreading,concurrency,java.util.concurrent,threadpoolexecutor,Java,Multithreading,Concurrency,Java.util.concurrent,Threadpoolexecutor,我认为使用我们可以提交Runnables以在构造函数中传递的BlockingQueue中执行,或者使用execute方法执行。 我的理解是,如果任务可用,它将被执行。 我不明白的是: public class MyThreadPoolExecutor { private static ThreadPoolExecutor executor; public MyThreadPoolExecutor(int min, int max, int idleTime, Bloc

我认为使用我们可以提交
Runnable
s以在构造函数中传递的
BlockingQueue
中执行,或者使用
execute
方法执行。
我的理解是,如果任务可用,它将被执行。
我不明白的是:

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);  

                }  
            });  
        }   


    }  


}
公共类MyThreadPoolExecutor{
私有静态线程池执行器;
公共MyThreadPoolExecutor(int-min、int-max、int-idleTime、BlockingQueue队列){
executor=新线程池executor(最小、最大、10、TimeUnit.MINUTES、queue);
//executor.prestartalcorethreads();
}  
公共静态void main(字符串[]main){
BlockingQueue q=新的LinkedBlockingQueue();
最后一个字符串[]名称={“A”、“B”、“C”、“D”、“E”、“F”};
对于(inti=0;i
除非我取消对
executor.prestartalcorethreads()的注释,否则此代码绝对不会执行任何操作或我调用打印
System.out.println(“+code+”)的runnable的
execute
(它也被注释掉)

为什么?
引述(我的重点):

默认情况下,即使是核心线程也会在最初创建并仅启动 当新任务到达时,但可以使用 方法prestartCoreThread()或prestartAllCoreThreads()。你可能 如果您使用非空值构造池,是否希望预启动线程 排队

嗯。所以我的队列不是空的。但是我创建了
执行器
,我执行
睡眠
,然后我将新的
可运行
添加到队列中(在循环中添加到100)。
这个循环不算是新任务到达了吗?

为什么它不能工作,我必须
预启动
或者明确地调用
执行

工作线程是在任务通过执行到达时产生的,这些线程与底层工作队列交互。如果从非空工作队列开始,则需要预先启动工人。看

我重复一遍,工人是与工作队列交互的人。它们仅在通过
execute
传递时按需生成。(或其上面的层,例如,
invokeAll
submit
,等等)如果它们没有启动,则无论您向队列添加了多少工作,因为没有任何检查,因为没有工作人员启动

ThreadPoolExecutor
在必要时或您通过方法和命令预先创建工作线程之前,不会生成工作线程。如果没有工人启动,那么就无法完成队列中的任何工作

添加初始
execute
有效的原因是它强制创建sole核心工作线程,然后可以开始处理队列中的工作。您还可以调用
prestartCoreThread
并接收类似的行为。如果要启动所有工作线程,必须调用
prestartAllCoreThreads
或通过
execute
提交该数量的任务

请参阅下面的执行代码

/**
 * 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);
}
/**
*在将来的某个时候执行给定的任务。任务
*可以在新线程或现有池线程中执行。
*
*如果任务无法提交执行,或者
*执行器已关闭或已达到其容量,
*该任务由当前的{@code RejectedExecutionHandler}处理。
*
*@param命令要执行的任务
*@Trows RejectedExecutionException由
*{@code RejectedExecutionHandler},如果任务
*无法接受执行
*如果{@code command}为空,@将引发NullPointerException
*/
public void execute(Runnable命令){
如果(命令==null)
抛出新的NullPointerException();
/*
*分三步进行:
*
*1.如果运行的线程少于corePoolSize,请尝试
*以给定命令作为第一个线程启动新线程
*对addWorker的调用以原子方式检查运行状态和
*workerCount,从而防止可能增加
*在不应该的情况下,通过返回false执行线程。
*
*2.如果任务可以成功排队,那么我们仍然需要
*再次检查是否应该添加线程
*(因为自上次检查以来,已有的已死亡)或
*自进入此方法后,池关闭。因此
*重新检查状态,如有必要,在以下情况下回滚排队
*已停止,如果没有线程,则启动新线程。
*
*3.如果无法对任务排队,则尝试添加新任务
*线程。如果它失败,我们知道我们已关闭或饱和
*所以拒绝这个任务。
*/
int c=ctl.get();
if(工作计数(c)