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()+ "线程结束...." ); |
} |
} |