Executor是java5之后提供的一个多线程框架java.util.concurrent,通过Executor提供的线程池来创建线程,他基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务的线程相当于消费者,并用Runnable来表示任务。
Executor提供了4中创建线程池的方法:
1、newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO, 优先级)执行。
返回一个ExecutorService,其中ExecutorService接口继承了Executor接口,是Executor的扩展子接口;
提供了两种执行任务的方法:
void execute(Runnable command)
Future<V> submit(Callable<V> task)
其中execute没有返回值,执行的是Runnable 实现类,而submit有future 返回值,执行的是Callable实现类,Future接口和它的实现FutureTask类,代表异步计算的结果,submit获取返回值get获取数据的时候,会导致get所在的线程发生堵塞,直到你返回值的线程执行完后,get线程才获取最终的结果;
public class SingleThreadExecutorTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
final String user = "user" + (i + 1);
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(user + "--"
+ Thread.currentThread().getName()
+ "执行完成----------");
}
});
}
pool.shutdown(); //关闭资源
}
}
2、newFixedThreadPool(int nThreads): 创建一个可重用固定数目线程的线程池,如果超过指定数目的任务,则需排队等待其他线程执行完成。
public class FixedThreadPoolTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5); //线程池的大小为5
for (int i = 0; i < 10; i++) {
final String user = "user"+(i+1);
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(user+"--"+Thread.currentThread().getName()+"--开始执行...");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(user+"--"+Thread.currentThread().getName()+"--执行完成");
}
});
}
pool.shutdown(); //释放
}
}
public class FutureTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5); // 线程池的大小为5
CompletionService<String> completionService = new ExecutorCompletionService<String>(
pool); //封装线程执行完后的结果
for (int i = 0; i < 5; i++) {
final String user = "user" + (i + 1);
completionService.submit(new Callable<String>() {
@Override
public String call() {
try {
Thread.sleep((long)(Math.random()*10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return user + "--" + Thread.currentThread().getName()
+ "执行完成----------";
}
});
}
for (int i = 0; i < 5; i++) {
try {
System.out.println(i+"结果:"+completionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
pool.shutdown();
System.out.println("Finished");
}
}
3、**newCachedThreadPool()**创建一个可缓存的线程池,先看池中是否存在以前创建的线程,如果有,就复用,如果没有就创建新的线程加入池中。缓存型池子通常用于执行一些生存期很短的异步型任务
public class CachedThreadPoolTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i <5; i++) {
final String user = "user"+(i+1);
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(user+"--"+Thread.currentThread().getName()+"--执行完成");
}
});
}
pool.shutdown();
}
}
4、newScheduledThreadPool(int corePoolSize):创建一个支持定时任务的定长线程池,它提供了3中定时烦方法。
public class ScheduledThreadPoolTest {
public static void main(String[] args) {
System.out.println("程序开始:" + System.currentTimeMillis());
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ "开始执行,当前时间:" + System.currentTimeMillis());
}
};
// 创建并执行在给定延迟后启用的一次性操作
//pool.schedule(runnable, 5000, TimeUnit.MILLISECONDS);
//创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推
pool.scheduleAtFixedRate(runnable, 1000, 5000, TimeUnit.MILLISECONDS);
//创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟
//pool.scheduleWithFixedDelay(runnable, 1000, 5000, TimeUnit.MILLISECONDS);
}
}