在Java之后并发线程这块发生了根本的变化最重要的莫过于新的启动调度管理线程的一大堆API了在Java以后通过Executor来启动线程比用Thread的start()更好在新特征中可以很容易控制线程的启动执行和关闭过程还可以很容易使用线程池的特性
一创建任务
任务就是一个实现了Runnable接口的类
创建的时候实run方法即可
二执行任务
通过ncurrentExecutorService接口对象来执行任务该接口对象通过工具类ncurrentExecutors的静态方法来创建
Executors此包中所定义的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory 和 Callable 类的工厂和实用方法
ExecutorService提供了管理终止的方法以及可为跟蹤一个或多个异步任务执行状况而生成 Future 的方法 可以关闭 ExecutorService这将导致其停止接受新任务关闭后执行程序将最后终止这时没有任务在执行也没有任务在等待执行并且无法提交新任务
executorServiceexecute(new TestRunnable())
创建ExecutorService
通过工具类ncurrentExecutors的静态方法来创建
Executors此包中所定义的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory 和 Callable 类的工厂和实用方法
比如创建一个ExecutorService的实例ExecutorService实际上是一个线程池的管理工具
ExecutorService executorService = ExecutorsnewCachedThreadPool()
ExecutorService executorService = ExecutorsnewFixedThreadPool()
ExecutorService executorService = ExecutorsnewSingleThreadExecutor()
将任务添加到线程去执行
当将一个任务添加到线程池中的时候线程池会为每个任务创建一个线程该线程会在之后的某个时刻自动执行
三关闭执行服务对象
executorServiceshutdown()
四综合实例
package concurrent;
import ncurrentExecutorService;
import ncurrentExecutors;
/**
* Created by IntelliJ IDEA
*
* @author leizhimin ::
*/
public class TestCachedThreadPool {
public static void main(String[] args) {
//ExecutorService executorService = ExecutorsnewCachedThreadPool();
ExecutorService executorService = ExecutorsnewFixedThreadPool();
// ExecutorService executorService = ExecutorsnewSingleThreadExecutor();
for (int i = ; i < ; i++) {
executorServiceexecute(new TestRunnable());
Systemoutprintln(************* a + i + *************);
}
executorServiceshutdown();
}
}
class TestRunnable implements Runnable {
public void run() {
Systemoutprintln(ThreadcurrentThread()getName() + 线程被调用了);
while (true) {
try {
Threadsleep();
Systemoutprintln(ThreadcurrentThread()getName());
} catch (InterruptedException e) {
eprintStackTrace();
}
}
}
}
运行结果
************* a *************
************* a *************
poolthread线程被调用了
************* a *************
poolthread线程被调用了
poolthread线程被调用了
************* a *************
************* a *************
poolthread线程被调用了
poolthread线程被调用了
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
五获取任务的执行的返回值
在Java之后任务分两类一类是实现了Runnable接口的类一类是实现了Callable接口的类两者都可以被ExecutorService执行但是Runnable任务没有返回值而Callable任务有返回值并且Callable的call()方法只能通过ExecutorService的submit(Callable<T> task) 方法来执行并且返回一个 <T> Future<T>是表示任务等待完成的 Future
public interface Callable<V>返回结果并且可能抛出异常的任务实现者定义了一个不带任何参数的叫做 call 的方法
Callable 接口类似于 Runnable两者都是为那些其实例可能被另一个线程执行的类设计的但是 Runnable 不会返回结果并且无法抛出经过检查的异常
Executors 类包含一些从其他普通形式转换成 Callable 类的实用方法
Callable中的call()方法类似Runnable的run()方法就是前者有返回值后者没有
当将一个Callable的对象传递给ExecutorService的submit方法则该call方法自动在一个线程上执行并且会返回执行结果Future对象
同样将Runnable的对象传递给ExecutorService的submit方法则该run方法自动在一个线程上执行并且会返回执行结果Future对象但是在该Future对象上调用get方法将返回null
遗憾的是在Java API文档中这块介绍的很糊涂估计是翻译人员还没搞清楚的缘故吧或者说是注释不到位下面看个例子
import javautilArrayList;
import javautilList;
import ncurrent*;
/**
* Callable接口测试
*
* @author leizhimin ::
*/
public class CallableDemo {
public static void main(String[] args) {
ExecutorService executorService = ExecutorsnewCachedThreadPool();
List<Future<String>> resultList = new ArrayList<Future<String>>();
//创建个任务并执行
for (int i = ; i < ; i++) {
//使用ExecutorService执行Callable类型的任务并将结果保存在future变量中
Future<String> future = executorServicesubmit(new TaskWithResult(i));
//将任务执行结果存储到List中
resultListadd(future);
}
//遍历任务的结果
for (Future<String> fs : resultList) {
try {
Systemoutprintln(fsget()); //打印各个线程(任务)执行的结果
} catch (InterruptedException e) {
eprintStackTrace();
} catch (ExecutionException e) {
eprintStackTrace();
} finally {
//启动一次顺序关闭执行以前提交的任务但不接受新任务如果已经关闭则调用没有其他作用
executorServiceshutdown();
}
}
}
}
class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
thisid = id;
}
/**
* 任务的具体过程一旦任务传给ExecutorService的submit方法则该方法自动在一个线程上执行
*
* @return
* @throws Exception
*/
public String call() throws Exception {
Systemoutprintln(call()方法被自动调用干活!!! + ThreadcurrentThread()getName());
//一个模拟耗时的操作
for (int i = ; i > ; i) ;
return call()方法被自动调用任务的结果是 + id + + ThreadcurrentThread()getName();
}
}
运行结果
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用干活!!! poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
call()方法被自动调用任务的结果是poolthread
Process finished with exit code