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);
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
