阻塞主线程执行本线程有两种方式:
1、使用future.get()
2、使用thread.join()
执行中的阻塞线程可以使用future.cancel()来取消,注意有一种特殊情形无法取消:
@Test
public void testFutureTask() {
ExecutorService executorService = Executors.newCachedThreadPool();
FutureTask<Boolean> futureTask1 = new FutureTask<>(new DemoCallable(1));
Thread thread1 = new Thread(futureTask1);
thread1.start();
new Thread(new CancelTool(futureTask1)).start();
try {
thread1.join();
} catch (Exception e) {
e.printStackTrace();
}
}
class DemoCallable implements Callable<Boolean> {
private Integer id;
public DemoCallable(int id) {
Thread.currentThread().setName(Thread.currentThread().getName() + id);
this.id = id;
}
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 30 ; i++) {
System.out.println(i + ":" + Thread.currentThread().getName());
Thread.sleep(1000);
}
return true;
}
}
// 用于取消future的执行
class CancelTool implements Runnable{
private Future<Boolean> future;
public CancelTool(Future<Boolean> future) {
this.future = future;
}
@Override
public void run() {
try {
// 第9秒后取消线程
Thread.sleep(9000);
future.cancel(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
执行单元测试testFutureTask,在这里我们使用thread.join()阻塞主线程,在CancelTool中我们设置future.cancel(false) , 可以发现在过了第9秒后,线程继续执行,没有按照预期被终止。
而如果我们将future.cancel(true)设置为true,可以发现在第九秒线程被终止了。
@Test
public void testFutureTask() {
ExecutorService executorService = Executors.newCachedThreadPool();
FutureTask<Boolean> futureTask1 = new FutureTask<>(new DemoCallable(1));
Thread thread1 = new Thread(futureTask1);
thread1.start();
new Thread(new CancelTool(futureTask1)).start();
try {
futureTask1.get();
} catch (Exception e) {
e.printStackTrace();
}
}
class DemoCallable implements Callable<Boolean> {
private Integer id;
public DemoCallable(int id) {
Thread.currentThread().setName(Thread.currentThread().getName() + id);
this.id = id;
}
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 30 ; i++) {
System.out.println(i + ":" + Thread.currentThread().getName());
Thread.sleep(1000);
}
return true;
}
}
// 用于取消future的执行
class CancelTool implements Runnable{
private Future<Boolean> future;
public CancelTool(Future<Boolean> future) {
this.future = future;
}
@Override
public void run() {
try {
// 第9秒后取消线程
Thread.sleep(9000);
future.cancel(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果我们使用future.get(),可以发现cancel方法的参数无论是true还是false,执行中的线程都能够在第九秒被终止。