1、任务
串行地执行任务:并发性能低
现式地为任务创建线程来执行任务:无限制的创建线程
无限制的创建线程的不足: 线程生命周期开销高、资源消耗、稳定性。
2、Executor框架:
Executor 接口 Executors 类 ExecutorService
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
void shutdown(); //缓慢关闭:不接受新的任务,等待未开始和执行中的任务完成之后关闭
List<Runnable> shutdownNow(); //立即关闭
boolean isShutdown();//是否关闭
boolean isTerminated(); //判断所有提交的任务是否完成(保证之前调用过shutdown方法)
//Callable 的 call() 方法可以返回壹個结果。方法 Runnable.run() 则不能返回结果。
<T> Future<T> submit(Callable<T> task);
// Future 对象可以用于判断 Runnable 是否结束执行
Future<?> submit(Runnable task);
}
public class Executors {
// 来一个任务创建一个线程,达到线程池大小之后不会创建新的线程
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
// 和Timer 相比,timer是基于绝对时间而 ScheduledExecutorService 是基于相对时间。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
private Executors() {}
......
}
3、线程状态
jvm只有在所有(非守护)线程全部终止时才会退出。
4、
Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作
// Future 接口
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
// FutureTask 类 是jdk中 Future 接口的唯一实现类
public class FutureTask<V> implements RunnableFuture<V> {
//构造函数1
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
//构造函数2
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
}
// RunnableFuture 接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
Callable 产生结果,Future拿到结果。
FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
那么这个组合FutureTask的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到