From:Java并发编程的艺术
- 目录
BiBi - 并发编程 -0- 开篇
BiBi - 并发编程 -1- 挑战
BiBi - 并发编程 -2- volatile
BiBi - 并发编程 -3- 锁
BiBi - 并发编程 -4- 原子操作
BiBi - 并发编程 -5- Java内存模型
BiBi - 并发编程 -6- final关键字
BiBi - 并发编程 -7- DCL
BiBi - 并发编程 -8- 线程
BiBi - 并发编程 -9- ReentrantLock
BiBi - 并发编程 -10- 队列同步器
BiBi - 并发编程 -11- 并发容器
BiBi - 并发编程 -12- Fork/Join框架
BiBi - 并发编程 -13- 并发工具类
BiBi - 并发编程 -14- 线程池
BiBi - 并发编程 -15- Executor框架
Java1.5之后把线程的工作单元和执行机制进行了分离。工作单元包括Runnable【无结果返回】和Callable【有结果返回】,执行机制由Executor框架提供。
Executor可以把一个Runnable对象封装为一个Callable对象。
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) { }
FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
SingleThreadExecutor和FixedThreadPool就前两个参数不一样。
CachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
使用SynchronousQueue没有容量的队列,每个插入操作必须等待另一个线程的对应移除操作。CachedThreadPool使用SynchronousQueue,把主线程提交的任务传递给空闲线程来执行【在60秒内】。
ScheduledThreadPoolExecutor
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
ScheduledThreadPoolExecutor继承ThreadPoolExecutor。DelayQueue是一个无界队列,它里面封装了一个PriorityQueue,会按照时间先后顺序进行排序,如果时间相同,则再按照任务添加的先后顺序。
执行过程:先从DelayQueue中获取已到期的ScheduleFutureTask进行执行,然后修改这个任务的time变量为下次执行的时间,最后将修改time后的ScheduleFutureTask放回到DelayQueue中。
FutureTask 异步计算结果
FutureTask继承了Future接口和Runnable接口。
构造函数:
FutureTask(Callable<V> callable) { }
FutureTask(Runnable runnable, V result) { }
开启线程的方法:
//方法一:继承于Thread
new Thread() {
@Override
public void run() {
}
}.start();
//方法二:实现Runnable接口
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
//方法三:FutureTask + Callable, 有结果返回
FutureTask<String> res = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
return null;
}
}).run();
//方法四:FutureTask + Runnable, 有结果返回
String result = null;
new FutureTask<String>(new Runnable() {
@Override
public void run() {
}
}, result).run();
注意:FutureTask调用run方法启动线程而不是start方法。
FutureTask使用场景:当一个线程需要等待另一线程把某个任务执行完后才能继续执行。
FutureTask的实现基于AQS同步器。FutureTask的acquire操作对应为get()/get(long timeout);release操作对应为run方法或cancel方法。
网友评论