java – ThreadPoolExecutor和队列
我认为使用
ThreadPoolExecutor我们可以提交Runnables,以便在构造函数中传递的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); } }); } } } 除非我取消注释executor.prestartAllCoreThreads();否则此代码不会执行任何操作.在构造函数中或者我调用runnable的执行来打印System.out.println(“”); (它也被注释掉了). 为什么?
好.所以我的队列不是空的.但我创建了执行程序,我睡觉然后我将新的Runnables添加到队列中(在循环中为100). 解决方法
当执行任务到达时,将生成工作线程,这些是与底层工作队列交互的线程.如果以非空工作队列开始,则需要预启动工作程序.见
implementation in OpenJDK 7.
我再说一遍,工人是与工作队列互动的工人.它们仅在通过execute传递时按需生成. (或者它上面的层,例如invokeAll,submit等)如果它们没有启动,那么你添加到队列中的工作量并不重要,因为没有任何工作人员启动就没有检查它. ThreadPoolExecutor不会在必要之前生成工作线程,或者如果您通过方法prestartAllCoreThreads和prestartCoreThread抢占它们的创建.如果没有工作程序启动,那么您的队列中的任何工作都无法完成. 添加初始执行的原因是它强制创建唯一的核心工作线程,然后该线程可以开始处理队列中的工作.您还可以调用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); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |