shutdownNow,执行后不再接受新任务,如果有等待任务,移出队列;有正在执行的,尝试停止之
==========================
通常shutdown之后调用awaitTermination,作用是:后者会阻塞当前线程,等待剩余任务执行完,然后继续往下执行。如果不适用await,那么shutdown之后,很可能导致剩余任务得不到执行(整个程序退出),或是执行出现异常(某些资源被释放之类)。
==========================
例子,网上来的,懒得动手写:
================
import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
/*
* Callable 和 Future接口
* Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
* Callable和Runnable有几点不同:
* (1)Callable规定的方法是call(),而Runnable规定的方法是run().
* (2)Callable的任务执行后可返回值(任意类型),而Runnable的任务是不能返回值的。
* (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
* (4)运行Callable任务可拿到一个Future对象,
* Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
* 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
*/
public class CallableAndFuture {
/** *//**
* 自定义一个任务类,实现Callable接口
*/
public static class MyCallableClass implements Callable{
// 标志位
private int flag = 0
public MyCallableClass(int flag){
this.flag = flag
}
public String call() throws Exception{
if (this.flag == 0){
// 如果flag的值为0,则立即返回
return "flag = 0"
}
if (this.flag == 1){
// 如果flag的值为1,做一个无限循环
try {
while (true) {
System.out.println("looping.")
Thread.sleep(2000)
}
} catch (InterruptedException e) {
System.out.println("Interrupted")
}
return "false"
} else {
// falg不为0或者1,则抛出异常
throw new Exception("Bad flag value!")
}
}
}
public static void main(String[] args) {
// 定义3个Callable类型的任务
MyCallableClass task1 = new MyCallableClass(0)
MyCallableClass task2 = new MyCallableClass(1)
MyCallableClass task3 = new MyCallableClass(2)
// 创建一个执行任务的服务
ExecutorService es = Executors.newFixedThreadPool(3)
try {
// 提交并执行任务,任务启动时返回了一个 Future对象,
// 如果想得到任务执行的结果或者是异常可对这个Future对象进行 *** 作
Future future1 = es.submit(task1)
// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
System.out.println("task1: " + future1.get())
Future future2 = es.submit(task2)
// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
Thread.sleep(5000)
System.out.println("task2 cancel: " + future2.cancel(true))
// 获取第三个任务的输出,因为执行第三个任务会引起异常
// 所以下面的语句将引起异常的抛出
Future future3 = es.submit(task3)
System.out.println("task3: " + future3.get())
} catch (Exception e){
System.out.println(e.toString())
}
// 停止任务执行服务
es.shutdownNow()
}
}
线程池:线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。以下是引用网络答案:
shutDown()
当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。
shutdownNow()
根据JDK文档描述,大致意思是:执行该方法,线程池的状态立刻变成STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。
它试图终止线程的方法是通过调用Thread.interrupt()方法来实现的,但是大家知道,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, interrupt()方法是无法中断当前的线程的。所以,ShutdownNow()并不代表线程池就一定立即就能退出,它可能必须要等待所有正在执行的任务都执行完成了才能退出。
上面对shutDown()以及shutDownNow()作了一个简单的、理论上的分析。如果想知道why,则需要亲自打开JDK源码,分析分析。
想要分析shutDown()以及shutDownNow()源码,我建议首先要对ThreadPoolExecutor有个大概了解。因为关闭线程池的所有方法逻辑都在ThreadPoolExecutor中处理的。
详情:http://xtu-xiaoxin.iteye.com/blog/649677
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)