线程池杂记,想到哪就写到哪了。
线程池的种类
new FixedThreadPool
new SingleThreadExecutor
new CachedThreadPool
new ScheduledThreadPool
分析:newFixedThreadPool
JDK源码:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
从两段源码中可以看出:
corePoolSize == maximumPoolSize,所以称之为固定大小线程池
keepAliveTime 是默认值0
任务队列为无序阻塞队列:LinkedBlockingQueue<Runnable>
线程工厂:默认工程
线程池拒绝策略:默认拒绝策略
分析:SingleThreadExecutor
JDK源码:
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
从两段源码中可以看出:
与固定线程池区别,SingleThreadExecutor给出默认线程size为1,当线程出现问题挂起时,会新建另一个线程,线程池中始终保持有一个线程
分析:CachedThreadPool
JDK源码:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
这个线程池默认大小即corePoolSize为0,当没有任务时,在线程池中没有线程。
队列:SynchronousQueue<Runnable>()
此队列的特点是长度为0,队列中不会存储任务work,它的目的是交换任务work,即当线程池从队列拿去任务时,恰好是向队列中放置任务霎间。当有任务时会创建新的线程,线程超过60秒没有用则会被终结。
这种也称之为线程池的直接提交策略。这种策略需要线程具有无限增长的能力。
线程池扩展方法
当线程在执行前需要执行某任务,或线程执行完成后需要执行某任务时,我们可扩展线程池方法beforeExecutor(),afterExecutor()等
示例如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args){
// TODO Auto-generated method stub
ExecutorService es = new ThreadPoolExecutor(3, 3,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory()){
@Override
protected void beforeExecute(Thread t, Runnable r) {
// TODO Auto-generated method stub
super.beforeExecute(t, r);
System.out.println("执行之前");
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
// TODO Auto-generated method stub
super.afterExecute(r, t);
System.out.println("执行之后");
}
};
// ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
final int task =i;
es.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+"---loop--"+j+"---task--"+task);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
}
}
线程池的拒绝策略使用方式如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args){
// TODO Auto-generated method stub
ExecutorService es = new ThreadPoolExecutor(3, 3,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// TODO Auto-generated method stub
System.out.println("任务被丢弃");
}
})
// ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
final int task =i;
es.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+"---loop--"+j+"---task--"+task);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
}
}
给出固定线程池和指定的任务队列,当线程池中线程数达到最大并且任务队列满时,有新执行任务时,任务将会执行指定的拒绝策略