其实线程池的概念和数据库链接池的概念类似。线程池的作用就是为了避免系统频繁地创建和销毁线程。在线程池中,
总有几个活跃的线程,当你需要使用线程是,可以从池子中随便拿一个空闲线程,当完成工作是,并不是关闭线程,而是
将这个线程退回到池子,方便其他人使用。
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newCachedThreadPool()
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
public class ThreadPoolDemo {
public static class MyTask implements Runnable{
@Override
public void run() {
System.out.println(System.currentTimeMillis()+":Thread ID:"
+Thread.currentThread().getId());
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyTask task = new MyTask();
ExecutorService es = Executors.newFixedThreadPool(5);
for(int i = 0;i<10;i++){
es.execute(task);
}
}
}
上述代码中,我们创建了固定大小的线程池,内有5个线程。然后我们依次向线程池提交了10个任务。此后,线程池就会
1504283763066:Thread ID:10
1504283763066:Thread ID:9
1504283763066:Thread ID:12
1504283763067:Thread ID:13
1504283763067:Thread ID:11
1504283764066:Thread ID:9
1504283764066:Thread ID:10
1504283764066:Thread ID:12
1504283764067:Thread ID:11
1504283764067:Thread ID:13
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
由以上线程池的实现代码可以看到,它们都只是ThreadPoolExecutor类的封装。接下来看看ThreadPoolExecutor最重要的构造函数:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue)
函数的参数含义如下:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
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);
}
当我们使用线程池执行任务时,即使用execute()方法调用任务时,ThreadPoolExecutor的调度源代码如上面所示,
public class ThreadPoolDemo {
public static class MyTask implements Runnable{
@Override
public void run() {
System.out.println(System.currentTimeMillis()+":Thread ID:"
+Thread.currentThread().getId());
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
new LinkedBlockingDeque(10),
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{ System.out.println(r.toString()+"is discard");
}
});
for(int i =0;i
1504289276848:Thread ID:9
1504289276858:Thread ID:10
demo.ThreadPoolDemo$MyTask@28d76d1eis discard
demo.ThreadPoolDemo$MyTask@28d76d1eis discard
1504289276889:Thread ID:11
1504289276892:Thread ID:13