并发编程应用
第8章 结束线程与线程池任务
8.1 stop()与destroy()
JDK1.5以前版本,在Thread类中提供了stop()和destroy()方法,用于线程的停止和销毁。
stop()方法是不安全的,使用这个方法停止线程,可以解锁所有和该线程相关的监视器。那些原来受监视器保护的对象会处于不一致的状态,因此受损对象可能变得对其他线程可见,从而导致任意行为的发生。
destroy()方法的设计初衷是为了销毁线程,该线程所持有的任何监视器仍然保持锁定。但是,该方法从未真正实现。如果目标线程持有保护关键系统资源的锁,当线程被销毁后,则无法再次访问该资源,这将直接导致死锁。
8.2 状态值结束线程
参见3.3.3节,使用状态值结束线程运行。
8.3 shutdown()与shutdownNow()
如何使用shutdown()与shutdownNow()方法关闭线程池中的任务,参见4.1.2节和4.3.2节相关内容。
8.4 线程休眠
线程休眠就是使正在执行任务的线程,进入WAITING状态。这时会释放当前线程占用的监视器锁,而且CPU不会再给该任务分配资源。线程的WAITING与BLOCKED状态完全不同,这是一种非常经济的、不占用系统资源的休眠状态。
参见3.1节,通过Object对象的wait()/notify()方法,休眠或唤醒线程。
参见5.2节,通过Condition对象的await()/signal()方法,休眠或唤醒线程。
8.5 线程中断
参见3.3节线程中断内容。
8.6 Future与FutureTask
参见4.3.1节,任务实现Callable接口,通过ExecutorService的submit()提交任务,可以使用Future接收call()方法的返回值。
Future类表示异步计算的未来结果,这个结果最终将在处理完成后出现在Future中。返回结果只能在异步执行完成后使用get()方法进行检索。
get()方法是阻塞等待模式,如果异步线程未执行完成相应的任务,则接收线程只能阻塞等待,直到结果返回。
8.6.1 取消任务
调用Future中的cancel()方法,可以取消正在执行中的异步任务。
任务取消时,执行任务的线程处于TIMED_WAITING状态;任务执行完毕或取消任务后,执行任务的线程回到线程池,处于WAITING待命状态;等待超时,主线程发出cancel()指令后,异步任务都被立即结束了!
8.6.2 任务超时结束
Future的get(long timeout,TimeUnit unit)方法会在任务执行时间超过预期时,抛出TimeoutException异常,强制结束任务返回结果的接收,但是任务本身仍然继续运行。
第9章 Tomcat线程池技术
9.1 自定义ThreadPoolExecutor
Tomcat自定义了线程池,它继承了java.util.concurrent.ThreadPoolExecutor。这里新增了一个成员变量submittedCount,它用于监控已经提交但尚未完成的任务数量,这包括已经在队列中的任务和已经交给工作线