1.Excutor介绍
java SE5的java.util.concurrent包中的执行器(Executor)将管理Thread对象,简化了并发编程。Executor在客户端和任务执行之间提供了一个中间层;与客户端直接执行任务不同,这个中间对象将执行任务。Excutor允许管理异步任务的执行,而无需显式的管理线程的生命周期。
Excutor在Java SE5/6是启动任务的优选方法。
使用Executor来daitiThread对象在MoreBasicThreads.java。
如下:
package
jiangning.c21;
import
java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors;
public
class
CachedThreadpool {
public
static
void
main(String[] args) {
ExecutorService exec = Executors. newCachedThreadPool();
for
(
int
i=0; i<5; i++){
exec.execute(
new
LiftOff());
}
exec.shutdown();
}
}
/**
* 运行结果
* #3(9),#2(9),#0(9),#4(9),#1(9),#3(8),#1(8),#3(7),
* #1(7),#3(6),#1(6),#3(5),#1(5),#3(4),#1(4),#3(3),
* #1(3),#3(2),#1(2),#3(1),#1(1),#3(LiftOff!),#1(LiftOff!),
* #2(8),#0(8),#4(8),#2(7),#0(7),#4(7),#2(6),#0(6),
* #4(6),#0(5),#2(5),#4(5),#0(4),#2(4),#0(3),#4(4),
* #2(3),#0(2),#4(3),#2(2),#0(1),#4(2),#2(1),#0(LiftOff!),
* #4(1),#2(LiftOff!),#4(LiftOff!),
*/
经常看到Executor被用来创建和管理系统中的所有任务。
2. shutdown()方法:防止新任务提交给这个Executor。
当前线程(在本例中即main()线程)将继续运行在shutdown()被调用之前提交的所有任务。这个程序将在Executor中的所有任务完成之后尽快推出。
3.FixedThreadPool
创建有限的线程来提交任务。可以一次性预先执行代价高昂的线程分配,可以限制线程的数量。从而节约时间,因为不用为每个任务都固定地付出创建线程的开销。
在事件驱动的系统中,需要线程的事件处理器,通常直接从池中获取线程,尽快的得到服务。
注意:在任何线程池中,现有线程在可能的情况下,都会被自动复用。
如下:
package jiangning.c21;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadpool {
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(5);//固定线程数量
for(int i=0; i<5; i++){
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
/**
* 运行结果
* #2(9),#0(9),#3(9),#2(8),#0(8),#1(9),#3(8),
* #2(7),#0(7),#3(7),#1(8),#4(9),#2(6),#1(7),
* #3(6),#1(6),#3(5),#1(5),#3(4),#1(4),#3(3),
* #1(3),#3(2),#1(2),#3(1),#1(1),#3(LiftOff!),
* #0(6),#1(LiftOff!),#4(8),#2(5),#0(5),#2(4),
* #0(4),#4(7),#4(6),#4(5),#4(4),#4(3),#0(3),
* #4(2),#0(2),#2(3),#4(1),#0(1),#2(2),#4(LiftOff!),
* #0(LiftOff!),#2(1),#2(LiftOff!),
*/
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadpool {
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(5);//固定线程数量
for(int i=0; i<5; i++){
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
/**
* 运行结果
* #2(9),#0(9),#3(9),#2(8),#0(8),#1(9),#3(8),
* #2(7),#0(7),#3(7),#1(8),#4(9),#2(6),#1(7),
* #3(6),#1(6),#3(5),#1(5),#3(4),#1(4),#3(3),
* #1(3),#3(2),#1(2),#3(1),#1(1),#3(LiftOff!),
* #0(6),#1(LiftOff!),#4(8),#2(5),#0(5),#2(4),
* #0(4),#4(7),#4(6),#4(5),#4(4),#4(3),#0(3),
* #4(2),#0(2),#2(3),#4(1),#0(1),#2(2),#4(LiftOff!),
* #0(LiftOff!),#2(1),#2(LiftOff!),
*/
4.CachedThreadPool与FixedThreadPool
CachedThreadPool在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此CachedThreadPool是Executor的首选。只有当这种方式引发问题时候,才用FixedThreadPool。
5.SingleThreadExecutor
SingleThreadExecutor就像FixedTreadPool的线程数量是1的情况。这对于希望在另一个线程中连续运行的任何事物(长期存活的任务)来说,都是很有用的,例如监听进行套接字连接任务、更新本地或远程任务、事件分发线程。
如果向SingleThreadExecutor提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前运行结束,所有的任务将使用相同的线程。
SingleThreadExecutor会序列化所有提交给它的任务,并会维护它自己(隐藏)的悬挂队列。
如下:
package jiangning.c21;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for(int i=0; i<5; i++){
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
/**
* 运行结果
* #0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),
* #0(1),#0(LiftOff!),#1(9),#1(8),#1(7),#1(6),#1(5),
* #1(4),#1(3),#1(2),#1(1),#1(LiftOff!),#2(9),#2(8),
* #2(7),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),#2(LiftOff!),
* #3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),
* #3(1),#3(LiftOff!),#4(9),#4(8),#4(7),#4(6),#4(5),
* #4(4),#4(3),#4(2),#4(1),#4(LiftOff!),
*/
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for(int i=0; i<5; i++){
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
/**
* 运行结果
* #0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),
* #0(1),#0(LiftOff!),#1(9),#1(8),#1(7),#1(6),#1(5),
* #1(4),#1(3),#1(2),#1(1),#1(LiftOff!),#2(9),#2(8),
* #2(7),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),#2(LiftOff!),
* #3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),
* #3(1),#3(LiftOff!),#4(9),#4(8),#4(7),#4(6),#4(5),
* #4(4),#4(3),#4(2),#4(1),#4(LiftOff!),
*/