线程运行工具也有两种方法实现:
1、Thread
2、ThreadPool
- Executors.xxx.submit: 运行器 (submit, return Future)
- ThreadPoolExecutor.execute: 线程池运行器 (execute, void)
主要区别:线程池循环使用线程池中的线程,减少创建和销毁线程。
可以用Future接收运行结果
运行体主要有两种方法实现:
1、Runnable(), run()
2、Callable(), call()
主要区别:Run 没有返回值,Call有返回值。
可以把运行体封装成FutureTask。
一、准备线程
1、Thread
Thread t = new Thread([Runnable | Callable]);2、Thread Pool Executor
ExecutorService executor = Executors.newFixedThreadPool(n); // n threads; newSingleThreadExecutor(), newScheduledThreadPool(), ...
1、Run
new Runnable() {
public void run() {...}
}
2、Call
new Callable<String>() {
public String call() throws Exception {...; return ...} // e.g. return String type
}
3、FutureTask
Callable<String> task = ...; // or Runnable
FutureTask<String> ft = new FutureTask<String>(task); // e.g.String三、运行
1、Thread
t.start();2、Thread Pool Executor
executor.submit([Callable | Runnable])3、Future
Future<String> future = executor.submit(...) // similar to thread.start四、Sample
public class Thread01_future extends Thread {
public static void main(String[] args) {
// Future: 异步计算结果
// Thread.start: 运行器
// Executors.xxx.submit: 运行器
// ThreadPoolExecutor.execute: 线程池运行器
// (execute, void) (submit, return Future)
// FutureTask: 异步计算任务
// Runnable(), run(): 运行任务(运行类、运行方法,void)
// Callable(), call(): 运行任务(运行类、运行方法,return)
// test01();
// test02();
test03();
}
// Future: 异步计算结果
// Executors.xxx.submit: 运行器
// Runnable(), run(): 运行任务(运行类、运行方法,void)
// Callable(), call(): 运行任务(运行类、运行方法,return)
public static void test01() {
// 创建一个执行任务的服务
ExecutorService executor = Executors.newFixedThreadPool(3);
try {
// 1. A Runnable, however, does not return a result and cannot throw
// checked exception.
System.out.println("~~~1");
Future<?> runnable1 = executor.submit(new Runnable() {
@Override
public void run() {
System.out.println("runnable1 running.");
}
});
System.out.println("Runnable1:" + runnable1.get());
// 2. Callable
System.out.println("~~~2");
Future<String> future1 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "result=task1";
}
});
System.out.println("task1: " + future1.get());
// 3. 对Callable调用cancel可以对对该任务进行中断
System.out.println("~~~3");
Future<String> future2 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
try {
while (true) {
System.out.println("task2 running.");
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Interrupted task2.");
}
return "task2=false";
}
});
// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
Thread.sleep(101);
System.out.println("task2 cancel: " + future2.cancel(true));
// 4.用Callable时抛出异常则Future什么也取不到了
// 获取第三个任务的输出,因为执行第三个任务会引起异常
// 所以下面的语句将引起异常的抛出
System.out.println("~~~4");
Future<String> future3 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
throw new Exception("task3 throw exception!");
}
});
// Thread.sleep(133);
System.out.println("task3: " + future3.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 停止任务执行服务
executor.shutdownNow();
}
// FutureTask: 异步计算任务
// Thread, Executors.xxx.submit: 运行器
public static void test02() {
Callable<String> task = new Callable<String>() {
@Override
public String call() {
System.out.println("Sleep start.");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Sleep end.");
return "time=" + System.currentTimeMillis();
}
};
// 直接使用Thread的方式执行
FutureTask<String> ft = new FutureTask<String>(task);
Thread t = new Thread(ft);
t.start();
try {
System.out.println("waiting execute result");
System.out.println("result = " + ft.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 使用Executors来执行
System.out.println("=========");
FutureTask<String> ft2 = new FutureTask<String>(task);
Executors.newSingleThreadExecutor().submit(ft2);
try {
System.out.println("waiting execute result");
System.out.println("result = " + ft2.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// ThreadPoolExecutor.execute: 线程池运行器
public static void test03() {
int produceTaskMaxNumber = 4;
// 构造一个线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
new ThreadPoolExecutor.DiscardOldestPolicy());
ArrayList<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();
for (int i = 1; i <= produceTaskMaxNumber; i++) {
try {
// 产生一个任务,并将其加入到线程池
Callable<String> task = new Callable<String>() {
@Override
public String call() {
String task = "task@ ";
System.out.println("put " + task);
return task;
}
};
FutureTask<String> futureTask = new FutureTask<String>(
task);
threadPool.execute(futureTask);
tasks.add(futureTask);
} catch (Exception e) {
e.printStackTrace();
}
}
for (FutureTask<String> futureTask : tasks) {
// 1秒内获得结果 (1st arg: the maximum time to wait, 2nd arg: the time
// unit of the timeout argument)
String str = null;
try {
str = "stop " + futureTask.get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
System.out.println(str);
}
}
}
本文深入探讨了线程与线程池的实现方式,包括使用Thread和ThreadPoolExecutor,以及如何通过Future获取运行结果。通过示例展示了如何在不同场景下选择合适的运行体(Runnable或Callable),并利用FutureTask实现异步计算。同时,介绍了如何在ThreadPoolExecutor中提交任务以及如何使用Future来获取结果,强调了线程池在减少创建和销毁线程方面的作用。
385

被折叠的 条评论
为什么被折叠?



