java程序中如何中断正在运行的线程?

雪梦科技 发布于 2012/01/16 14:28
阅读 5K+
收藏 1

最近有个问题一直困扰我,那就是如何中断java线程。

我从网上看到java线程的stop,pause,resume方法已经不提倡了。

然后如果只是简单的设置一个变量进行标识的话,又可能碰到线程sleep,无法及时响应。

另外,中断还要考虑关闭socket,关闭IO等操作之后才能执行。

看过一些资料,还是有点糊涂。

有没有关于如何中断和结束java线程的比较详细的资料?

我想知道的就是

如何如何正确并且高效的中断或者结束正在执行的java线程。

请各位大佬帮忙释疑。谢谢~

加载中
1
Monkey
Monkey

引用来自“70岁”的答案

引用来自“Monkey”的答案

使用变量控制是最好的方式,或者是任务控制。大多数线程都是为了一个任务而诞生,只要这个任务完成就把他砍掉。如果是一些刷新的线程,变量控制,改变变量让线程停止,如果要重新启动就重新创建一个线程。

多线程使用要遵守一个最基本的原则,可控多线程,不要开一个线程去做无意义的事情,这样可能这个线程就无法控制了。通常三个层次的线程,一个UI绘制线程,一个业务处理线程,还有一个事物处理所需要的资源线程,比如你可能通过一个界面往外界发送数据,那么首先把界面数据封装成对象,传送到业务处理线程上,然后这个线程将对象转换成数据发送给一个线程去通过更底层的api将数据流发出去,而第二层往往是线程池。

最后只有在迫不得已的时候才使用多线程,多线程是下下策,而绝对不是上策。多线程能只能改善用户体验,而无法提升效率,只会降低效率。

变量控制有考虑到sleep吗?
假如必须你通过一个线程循环发送数据,当用户提交之后你的发动方法就开始运行了,正常时候一直循环知道发送数据完毕,但是这个时候用户取消,你直接把线程stop了,他不一定能把你那个运行的循环取消。这样会产生不可预测的后果。正常做法是你每一次循环发送之前都要检查一个标示如果这个标志改变就立刻停止发送,这才是好办法,你也不用调用stop这方法了。
ddatsh
ddatsh
@Monkey : 取消的时候,涉及资源之类的操作,肯定是需要仔细判断的
Monkey
Monkey
@dd : 并发的取消好像也只是改变一个状态值,你再线程内部通过检查这个值来决定是否接受。jvm直接屠杀掉一个线程会引发严重后果,比如写文件写到一般被屠杀了,一来文件数据被毁了,文件流还可能还没关闭,后面的人就悲剧了。文件无法保存了,而且数据还被毁了。
ddatsh
ddatsh
并发包里就提供了对线程停止什么的支持
0
ddatsh
ddatsh
研究下JAVA 5中的并发包
雪梦科技
雪梦科技
好的,谢谢~
0
70岁
70岁
Executors.newCachedThreadPool()缓存型线程池,看看api不知道能不能解决你的问题呢。
雪梦科技
雪梦科技
@70岁 : 好的,谢谢~ 线程池还不太会用,研究下先~
70岁
70岁
@snowdream : 自己管理线程和线程池去管理线程,我更倾向于后者.
雪梦科技
雪梦科技
撇开android不说,是不是如果java程序中要用到多个线程,最好的方案就是使用线程池?
70岁
70岁
@snowdream : 那就看怎么设计了,对于android我没有太多的研究,建议先看看刚才的api。
雪梦科技
雪梦科技
如果我用到多线程,就必须用到线程池吗? 如果是android程序,整个程序都共享这个线程池?
0
Monkey
Monkey

使用变量控制是最好的方式,或者是任务控制。大多数线程都是为了一个任务而诞生,只要这个任务完成就把他砍掉。如果是一些刷新的线程,变量控制,改变变量让线程停止,如果要重新启动就重新创建一个线程。

多线程使用要遵守一个最基本的原则,可控多线程,不要开一个线程去做无意义的事情,这样可能这个线程就无法控制了。通常三个层次的线程,一个UI绘制线程,一个业务处理线程,还有一个事物处理所需要的资源线程,比如你可能通过一个界面往外界发送数据,那么首先把界面数据封装成对象,传送到业务处理线程上,然后这个线程将对象转换成数据发送给一个线程去通过更底层的api将数据流发出去,而第二层往往是线程池。

最后只有在迫不得已的时候才使用多线程,多线程是下下策,而绝对不是上策。多线程能只能改善用户体验,而无法提升效率,只会降低效率。

0
70岁
70岁

引用来自“Monkey”的答案

使用变量控制是最好的方式,或者是任务控制。大多数线程都是为了一个任务而诞生,只要这个任务完成就把他砍掉。如果是一些刷新的线程,变量控制,改变变量让线程停止,如果要重新启动就重新创建一个线程。

多线程使用要遵守一个最基本的原则,可控多线程,不要开一个线程去做无意义的事情,这样可能这个线程就无法控制了。通常三个层次的线程,一个UI绘制线程,一个业务处理线程,还有一个事物处理所需要的资源线程,比如你可能通过一个界面往外界发送数据,那么首先把界面数据封装成对象,传送到业务处理线程上,然后这个线程将对象转换成数据发送给一个线程去通过更底层的api将数据流发出去,而第二层往往是线程池。

最后只有在迫不得已的时候才使用多线程,多线程是下下策,而绝对不是上策。多线程能只能改善用户体验,而无法提升效率,只会降低效率。

变量控制有考虑到sleep吗?
Monkey
Monkey
变量控制线程是否结束,sleep只是线程如何运行,两者不矛盾。只不过变量控制的线程一旦结束这个线程就被废弃了,你要重新创建线程运行。
0
70岁
70岁

引用来自“Monkey”的答案

引用来自“70岁”的答案

引用来自“Monkey”的答案

使用变量控制是最好的方式,或者是任务控制。大多数线程都是为了一个任务而诞生,只要这个任务完成就把他砍掉。如果是一些刷新的线程,变量控制,改变变量让线程停止,如果要重新启动就重新创建一个线程。

多线程使用要遵守一个最基本的原则,可控多线程,不要开一个线程去做无意义的事情,这样可能这个线程就无法控制了。通常三个层次的线程,一个UI绘制线程,一个业务处理线程,还有一个事物处理所需要的资源线程,比如你可能通过一个界面往外界发送数据,那么首先把界面数据封装成对象,传送到业务处理线程上,然后这个线程将对象转换成数据发送给一个线程去通过更底层的api将数据流发出去,而第二层往往是线程池。

最后只有在迫不得已的时候才使用多线程,多线程是下下策,而绝对不是上策。多线程能只能改善用户体验,而无法提升效率,只会降低效率。

变量控制有考虑到sleep吗?
假如必须你通过一个线程循环发送数据,当用户提交之后你的发动方法就开始运行了,正常时候一直循环知道发送数据完毕,但是这个时候用户取消,你直接把线程stop了,他不一定能把你那个运行的循环取消。这样会产生不可预测的后果。正常做法是你每一次循环发送之前都要检查一个标示如果这个标志改变就立刻停止发送,这才是好办法,你也不用调用stop这方法了。
那如果在并发量很大的情况下,你该怎么控制?
0
Monkey
Monkey

引用来自“70岁”的答案

引用来自“Monkey”的答案

引用来自“70岁”的答案

引用来自“Monkey”的答案

使用变量控制是最好的方式,或者是任务控制。大多数线程都是为了一个任务而诞生,只要这个任务完成就把他砍掉。如果是一些刷新的线程,变量控制,改变变量让线程停止,如果要重新启动就重新创建一个线程。

多线程使用要遵守一个最基本的原则,可控多线程,不要开一个线程去做无意义的事情,这样可能这个线程就无法控制了。通常三个层次的线程,一个UI绘制线程,一个业务处理线程,还有一个事物处理所需要的资源线程,比如你可能通过一个界面往外界发送数据,那么首先把界面数据封装成对象,传送到业务处理线程上,然后这个线程将对象转换成数据发送给一个线程去通过更底层的api将数据流发出去,而第二层往往是线程池。

最后只有在迫不得已的时候才使用多线程,多线程是下下策,而绝对不是上策。多线程能只能改善用户体验,而无法提升效率,只会降低效率。

变量控制有考虑到sleep吗?
假如必须你通过一个线程循环发送数据,当用户提交之后你的发动方法就开始运行了,正常时候一直循环知道发送数据完毕,但是这个时候用户取消,你直接把线程stop了,他不一定能把你那个运行的循环取消。这样会产生不可预测的后果。正常做法是你每一次循环发送之前都要检查一个标示如果这个标志改变就立刻停止发送,这才是好办法,你也不用调用stop这方法了。
那如果在并发量很大的情况下,你该怎么控制?
并发量大也无所谓啊,并发量大只不过是同时运行的线程多了而已。每一个线程任然是持有各自的状态值啊,你要取消张三只要把张三的值改变,等到张三运行的时候发现自己被取消了他就自己把相关资源释放,然后退出。
有时候你可能还要让这个线程恢复到被取消的状态继续运行,那么也是在这个线程被取消之后把自己的状态告诉给一个管理状态的人,然后张三退出,如果需要张三重新运行也是将存储的值拿出来初始化到张三被杀的那个时候,然后启动这个伪张三线程。
0
张亮亮
张亮亮

Stop()方法虽然不推荐使用了,但是,还是可以使用的。

试想:你是一个平台提供商,要运行第三方的插件,但是第三方插件可能在运行一个死循环,为了避免资源浪费,平台提供商应该能够检测并通知该线程停止,如果过了一定时间之后仍不停止,就必须强制 stop() 了。

所以,个人觉得:
1. 先约定 线程控制变量的接口,需要由线程运行对象实现。
2. 平台运行商的任务调度器从线程池中租借线程运行该线程运行对象,并监控(如果需要的话)
3. 当需要停止时该线程运行对象时(资源耗尽,停应用?停机?),(1)先调用实现约定的接口,(2)调用对应线程的interrupt()方法以中断其休眠。而线程运行对象在被告知停止、或被 interrupt() 时,都应当适当的关闭相关资源,并自行结束。
4. 如果按照约定的超时时间之后,该线程仍未停止,则需要强制调用 stop()方法了。(此时该线程运行对象要么设计\编码不合理,要么故意的破坏程序)。

个人见解,共勉 ~~~~

0
徐迎龙
徐迎龙

在某线程中设置变量boolean isstop=false,需要停止该线程时候,线程之外的程序设置改变量为true,线程中只要判断该变量的值是否停止既可.不要使用线程stop方法,stop可能引起非可控后果

见<<Effective Java>>

0
浪客Dandy
浪客Dandy

应该使用变量来表示该线程是否该结束,使用stop和interrupt都是错误的。

我看大部分人都明白了嘛

返回顶部
顶部