package fengke.thread;
/**
* 线程的停止
* @author 锋客
* 内容:线程的停止共有三种方法:
* 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
* 2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
* 3. 使用interrupt方法中断线程。
*
*/
public class ThreadStop extends Thread{
public volatile boolean exit=true;
@Override
public void run() {
while(exit){
System.out.println(getName()+"线程正在运行....");
}
System.out.println("线程结束第一阶段!!!");
}
public static void main(String[] args) {
stopThread();
System.out.println("********stop()*********");
stopThread2();
System.out.println("********interrupt()*********");
stopThread3();
}
//使用标志退出
public static void stopThread(){
/*
* 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
* 2. 使用join()方法,会是线程抢先执行完毕,
* 可以通过 System.out.println("线程结束第二阶段!!!")
* System.out.println("线程结束第一阶段!!!")
* 的位置看出区别
* 3.最好使用这种方式结束进程
*/
ThreadStop ts = new ThreadStop();
ts.setName("标志");
ts.start();
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ts.exit=false;
try {
ts.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程结束第二阶段!!!");
System.out.println("***********************");
}
//使用stop()终止
public static void stopThread2(){
ThreadStop ts = new ThreadStop();
ts.setName("stop");
ts.start();
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ts.stop();
System.out.println("***********************");
}
/*
* 使用interrupt方法
* 类似于标志
* 注意在终止线程中,最好不能有sleep()等方法,否则有肯能是中断失败
* interrupt的定义:
*
* isInterrupted()方法仅仅是检查了当前线程的中断状态,但是不会清除这个状态
* 静态方法interrupted()这个方法同样是检测当前线程的中断状态,但是这个方法会产生一个副作用,就是会清除当前线程的中断状态。
*
* Thread.interrupt() VS Thread.stop()这两个方法最大的区别在于:
* interrupt()方法是设置线程的中断状态,让用户自己选择时间地点去结束线程;
* 而stop()方法会在代码的运行处直接抛出一个ThreadDeath错误,这是一个java.lang.Error的子类。
* 所以直接使用stop()方法就有可能造成对象的不一致性。
*
* interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,
* 这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,
* 那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。 如果线程没有被阻塞,
* 这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。
* 线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.
* 但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。
* 如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,
* 而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException.
* 若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,
* 那InterruptedException是不会被抛出来的.
*
*/
public static void stopThread3(){
ThreadStopInterrupt ts = new ThreadStopInterrupt();
ts.setName("interrupt");
ts.start();
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ts.interrupt();
System.out.println("***********************");
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("interrupt方法结束");
}
}
class ThreadStopInterrupt extends Thread{
public void run() {
while(!this.interrupted()){
System.out.println(getName()+"线程正在运行....");
// 线程中使用sleep()等一些方法会使中断失败
// try {
// sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
System.out.println(getName()+"线程结束....");
}
}