终结任务
2.2 在任务阻塞时终结
sleep()方法将线程由执行状态变为阻塞状态
线程状态:
新建(new):当线程被创建时,线程会短暂地处于这种状态。此时,线程已经被分配了必需的系统资源,并执行了初始化。此时线程已经有资格获得CPU的时间,此时只是有能力去争取CPU的时间。之后 ,调度器将把这个线程转变为可就绪或者阻塞状态
就绪(Runnable):在这种状态下,线程调度器只要将时间片分配给线程,线程就可以运行。在任意的时刻,线程可以运行也可以不运行,就看调度器是否分配时间片
阻塞(Blocked):线程能够运行,但某个条件阻碍了运行。当一个线程t处于阻塞状态下,调度器就会忽略线程,不会再分配给t任何的CPU时间。只有当t重新进入就绪状态,t才有可能被分给CPU时间片,才可能执行操作
死亡(Dead):处于死亡或者终止状态的线程将不再拥有是可调度的。并且也不可能再有资格去得到CPU时间片,线程的任务已经结束。任务死亡的通常做法就是run()执行结束返回
进入阻塞状态的可能原因:
调用了sleep()方法,任务进入休眠。此时,线程在指定的时间内不会运行
调用了wait()方法使线程挂起。直到线程得到notify(),notifyAll(),线程才会进入就绪状态
线程在等个某个输入输出完成
线程试图在某个对象上调用其同步方法,但此时对象锁被另一个线程持有不可用
对于处于阻塞状态的线程,必须强制这个线程跳出阻塞状态后,才可以让线程主动地终止
其实这一节重点是线程生命周期,至于终结本身,只是两个方法,和如何终结而已;
Thread.interrupt(); 进行中断
Thread.interrupted() 用以检查中断
线程协作
到重点了啦 ,书上的例子除了太长以外,都是经典啊;
一辆车要先打蜡,再抛光;
这里就存在一步要等另外一步,一辆车每两个线程;抛光需要等待打蜡;,打蜡结束后,打蜡需要叫醒抛光的人;
public class WaxOMatic {
public static void main(String[] args) throws InterruptedException {
Car car = new Car();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new WaxOff(car));
executorService.execute(new WaxOn(car));
TimeUnit.SECONDS.sleep(5);
executorService.shutdownNow();//中断全部线程
}
}
class Car{
private boolean waxOn = false;//用来表示打蜡-抛光的处理状态
/**
* 打蜡完成
*/
public synchronized void waxed(){
waxOn = true;//准备进行buffed抛光
notifyAll();
}
/**
* 抛光完成
*/
public synchronized void buffed(){
waxOn = false;// 准备为另一个 进行 waxed 打蜡
notifyAll();
}
/**
* 正在抛光,等待着准备打蜡
* @throws InterruptedException
*/
public synchronized void waitForWaxing() throws InterruptedException {
while (!waxOn){
wait();
}
}
/**
* 正在打蜡,等待着准备抛光
* @throws InterruptedException
*/
public synchronized void waitForBuffing() throws InterruptedException {
while (waxOn){
wait();
}
}
}
class WaxOn implements Runnable{
private Car car;
public WaxOn(Car car) {
this.car = car;
}
@Override
public void run() {
try
{
while (!Thread.interrupted()){
System.out.println("开始打蜡");
TimeUnit.MILLISECONDS.sleep(200);//模拟打蜡用的时间
car.waxed();//打蜡完成
car.waitForBuffing();
}
}catch (InterruptedException e){
System.out.println("打蜡 --> 中断异常");
}
System.out.println("完成打蜡");
}
}
class WaxOff implements Runnable{
private Car car;
public WaxOff(Car car) {
this.car = car;
}
@Override
public void run() {
try
{
while (!Thread.interrupted()){
car.waitForWaxing();
System.out.println("开始抛光");
TimeUnit.MILLISECONDS.sleep(200);//模拟抛光时间
car.buffed();//抛光完成
}
}catch (InterruptedException e){
System.out.println("抛光 --> 中断异常");
}
System.out.println("完成抛光");
}
}
notify()和notifiyAll()
notify()用于唤醒特定的任务;有一个锁,很多任务在等它,那么你就可以使用notify()来特定唤醒
notifyAll()唤醒一个锁下面的全部任务;