Java停止线程及有锁时停止方法
2017-01-07 16:15
183 查看
当我们刚学完Thread一个线程t1之后,迫不及待地键入t1.start()开始启动线程,肯定思考过如何将这个线程停下来
其实原理只有一个,那就是让run方法结束
要知道开启多线程运行,其运行代码通常都是循环结构,只要控制住循环就可以让run方法结合苏,也就是线程结束
比如写个代码
这个小程序很简单,就是让两个线程一直跑,跑到60次之后就break,想法是好的,这个程序我是不会去跑的,因为我知道这个是无限循环,while(true)这个标记让它一直转
所以如果while(true)这个标记能够控制住,这个小程序就能停下来
可以定义个flag=true,再定义个changeFlag()方法,这个方法里面将flag切换为false
将while(true)改为while(false)
如果num++=60,就调用changeFlag方法
但是有一种情况,程序也停不下来
就是同步
*run()方法若是同步函数,且在while内try一个wait(),抛出InterruptedException,这时候运行也做了changeFlag()改变,程序就不会停下来;
如图,程序没有停下来,但是并不占用资源,不是死循环,因为wait在那儿了
当主线程while(true)的时候一直在转,到num==60的时候,st.changeFlag()也读了。可是开启两个线程之后,无论什么时候抢到CPU资源,都去public
synchronized void run(){}里面去运行
Thread-0进去之后,拿到一把锁,然后wait()了,放弃了资格,然后Thread-1进去也释放资格了,然后这两个都挂在这儿不动了;
主线程执行完了,还有两个线程存活,这个就是问题,改变了标记flag但是没有结束线程
也就是当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
**只有wait()结束之后再去while(flag)循环,读到标记才能结束。
我们可以强制做这件事情
在Thread中提供了一个方法叫interrupt()方法,叫做中断线程:如果线程在调用Object类的wait()等方法,或者join和sleep受阻,则其终端状态江北清除;中断状态也就是Wait,还会收到一个InterruptException;但是中断并不是stop,只是挂起
这时候,我可以强制清除其中断状态,强制地恢复到运行状态
4000
wait就像是催眠,催眠师拿个表将他吹眠之后进入中断状态,随后又用他的方法把他叫醒了;但现在,催眠师又把他催眠到中断状态,然后出国了。。。这时候要他醒过来怎么办,我又不会催眠师的方法,那我就一砖头下去把他呼醒得了
但是受伤了,发生异常了
现在对t1和t2下手,改变主函数的if内部:
完整如下:
看打印结果,Thread-0出现了终端异常,这就是因为t1的中断状态被强制清除了,所以产生了中断异常,但是程序还挂着不动,可以看到catch到异常之后又处理了一次,打印了Thread_0…run,之后此线程又回到了while(flag), 此时flag依旧为true,接着wait,又挂了
所以知道这个原因之后就很好解决了,
也就是只要发生异常,就代表有人在强制清除其中断状态,那么就在处理这个异常的时候,将flag标记为false,就可以完美结束了。
总结就是
当没有指定的方法让冻结的线程恢复到运行状态时,这就需要对冻结进行清除
强制让线程恢复到运行状态中来,就可以操作标记flag,让线程结束
Thread类提供该方法,interrupt( );
其实原理只有一个,那就是让run方法结束
要知道开启多线程运行,其运行代码通常都是循环结构,只要控制住循环就可以让run方法结合苏,也就是线程结束
比如写个代码
class StopThread implements Runnable { public synchronized void run() { while(true) { System.out.println(Thread.currentThread().getName()+"...run"); } } } public class StopThreadDemo { public static void main(String[] args) { StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++==60) { break; } System.out.println(Thread.currentThread().getName()+"......"+num); } } }
这个小程序很简单,就是让两个线程一直跑,跑到60次之后就break,想法是好的,这个程序我是不会去跑的,因为我知道这个是无限循环,while(true)这个标记让它一直转
所以如果while(true)这个标记能够控制住,这个小程序就能停下来
可以定义个flag=true,再定义个changeFlag()方法,这个方法里面将flag切换为false
将while(true)改为while(false)
如果num++=60,就调用changeFlag方法
class StopThread implements Runnable { private boolean flag=true;//************** public void run() { while(flag)//************** { System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeFlag()//************** { flag=false; } } public class StopThreadDemo { public static void main(String[] args) { StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++==60) { st.changeFlag();//************** break; } System.out.println(Thread.currentThread().getName()+"......"+num); } } }
但是有一种情况,程序也停不下来
就是同步
public synchronized void run() { while(flag)//************** { try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"...Exception"); flag=false; } System.out.println(Thread.currentThread().getName()+"...run"); } }
*run()方法若是同步函数,且在while内try一个wait(),抛出InterruptedException,这时候运行也做了changeFlag()改变,程序就不会停下来;
如图,程序没有停下来,但是并不占用资源,不是死循环,因为wait在那儿了
当主线程while(true)的时候一直在转,到num==60的时候,st.changeFlag()也读了。可是开启两个线程之后,无论什么时候抢到CPU资源,都去public
synchronized void run(){}里面去运行
Thread-0进去之后,拿到一把锁,然后wait()了,放弃了资格,然后Thread-1进去也释放资格了,然后这两个都挂在这儿不动了;
主线程执行完了,还有两个线程存活,这个就是问题,改变了标记flag但是没有结束线程
也就是当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
**只有wait()结束之后再去while(flag)循环,读到标记才能结束。
我们可以强制做这件事情
在Thread中提供了一个方法叫interrupt()方法,叫做中断线程:如果线程在调用Object类的wait()等方法,或者join和sleep受阻,则其终端状态江北清除;中断状态也就是Wait,还会收到一个InterruptException;但是中断并不是stop,只是挂起
这时候,我可以强制清除其中断状态,强制地恢复到运行状态
4000
wait就像是催眠,催眠师拿个表将他吹眠之后进入中断状态,随后又用他的方法把他叫醒了;但现在,催眠师又把他催眠到中断状态,然后出国了。。。这时候要他醒过来怎么办,我又不会催眠师的方法,那我就一砖头下去把他呼醒得了
但是受伤了,发生异常了
现在对t1和t2下手,改变主函数的if内部:
if(num++=60) { t1.interrupt(); t2.interrupt(); st.changeFlag(); break; }
完整如下:
class StopThread implements Runnable { private boolean flag=true; public synchronized void run() { while(flag) { try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"...Exception"); //flag=false; } System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeFlag() { flag=false; } } public class StopThreadDemo { public static void main(String[] args) { StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++==60) { t1.interrupt(); //st.changeFlag(); break; } System.out.println(Thread.currentThread().getName()+"......"+num); } System.out.println("over"); } }
看打印结果,Thread-0出现了终端异常,这就是因为t1的中断状态被强制清除了,所以产生了中断异常,但是程序还挂着不动,可以看到catch到异常之后又处理了一次,打印了Thread_0…run,之后此线程又回到了while(flag), 此时flag依旧为true,接着wait,又挂了
所以知道这个原因之后就很好解决了,
也就是只要发生异常,就代表有人在强制清除其中断状态,那么就在处理这个异常的时候,将flag标记为false,就可以完美结束了。
class StopThread implements Runnable { private boolean flag=true; public synchronized void run() { while(flag) { try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"...Exception"); flag=false; } System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeFlag() { flag = false; } } public class StopThreadDemo { public static void main(String[] args) { StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++==60) { t1.interrupt(); t2.interrupt(); st.changeFlag(); break; } System.out.println(Thread.currentThread().getName()+"......"+num); } System.out.println("over"); } }
总结就是
当没有指定的方法让冻结的线程恢复到运行状态时,这就需要对冻结进行清除
强制让线程恢复到运行状态中来,就可以操作标记flag,让线程结束
Thread类提供该方法,interrupt( );
相关文章推荐
- 停止Java线程,小心interrupt()方法
- Java安全停止线程方法
- java 多线程(1) join() / interrupt() 打断sleep() / stop() / run() / 线程停止的方法
- 停止java线程方法,小心interrupt
- java线程停止的方法
- java中的interrupt和stop方法——java中线程停止的方法
- 转: Java安全停止线程方法
- Java中停止线程执行的方法
- Java停止一个线程的几种方法
- Java中两种停止线程的方法
- 停止Java线程,小心interrupt()方法
- Java中停止线程执行的方法
- java 线程停止的方法
- 停止Java线程,小心interrupt()方法
- Java安全停止线程方法
- java 线程停止的方法
- 停止Java线程,小心interrupt()方法
- 停止Java线程,小心interrupt()方法
- [改善Java代码]不使用stop方法停止线程
- java多线程(三)停止Java线程,小心interrupt()方法