关于关闭线程的一些讨论

zxhcloth 2012-12-17 12:02:27
就本人知识而言,对线程的关闭一直都不是很顺利
1、通过状态位,程序不正常时,这个很不好使
2、线程阻塞,通过interrupted让线程抛异常
3、I/O阻塞,如果是自己写的相关程序可以通过Socket.close()等方法退出阻塞,但如果是别人封装好的应用呢,实在不知道怎么退出阻塞

以上是本人在不同项目中使用并遇到的问题。希望能有大牛能指点迷津,或者大家谈谈各自是怎么解决的。
为方便讨论,我举个例子:
我在一个邮件接收的容器里,开启了10几个线程分别连接不同账号进行邮件接收,经常是运行一段时间后,某些线程就阻塞在那里了,而我没有办法让它退出阻塞,就只能重启容器。
...全文
261 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
线程本身自己就应该有阻塞机制,他启动的时候就记录自己的启动时间,自己判断自己做某个操作是否超时了,自己决定是否结束自己。
dracularking 2012-12-19
  • 打赏
  • 举报
回复
会是什么第三方包居然不提供阻塞超时呢(我觉得这个是起码要提供的),还是没用对呢
zxhcloth 2012-12-19
  • 打赏
  • 举报
回复
这么快就沉了,自己刷下。
zxhcloth 2012-12-19
  • 打赏
  • 举报
回复
氛围没起来,还是要感谢回帖的专家们。结贴!
lizhen19870211 2012-12-17
  • 打赏
  • 举报
回复
如果是第三方包的问题,你换一个不就完了么。即使你重写了第三方包的相关方法,也可能带来其他问题。
zxhcloth 2012-12-17
  • 打赏
  • 举报
回复
to:lizhen19870211 朋友,你一直在说锁、等待,其实这个如果是我自己做,好解决,并发、线程安全这块我还是比较有心得的。 因为多线程、并发这块的应用,一般很少用别人的。所以这块不算是什么大问题。 问题是I/O阻塞,只要是通信相关的都有这个问题,如果是用了别人封装的包,阻塞问题真的是很蛋疼。
安特矮油 2012-12-17
  • 打赏
  • 举报
回复
不知道你说的阻塞是死锁还是指的线程阻塞等待呢?如果是后者那只能说明这个线程正在等待输入而已,应该不存在什么问题,你可以考虑给他一个输入就可以了。如果是死锁的话就需要检查一下你的代码了
oFengKun 2012-12-17
  • 打赏
  • 举报
回复
引用 4 楼 lizhen19870211 的回复:遇到线程阻塞的问题最好是看看代码中,哪个地方获取了对象锁。即使是在jar也可以看看他的源代码里那块获取了对象锁,比如IO操作,同步方法,同步块等。只要同步了,那么就只有一个线程可以获取对象锁访问当前被同步的对象,其他的线程必须等待。要尽量在关键位置降低或减少这些操作(如,关键位置总是用log4j记很多日志)至于怎么监控线…… dingqi
lizhen19870211 2012-12-17
  • 打赏
  • 举报
回复
引用 5 楼 zxhcloth 的回复:
引用 4 楼 lizhen19870211 的回复:遇到线程阻塞的问题最好是看看代码中,哪个地方获取了对象锁。即使是在jar也可以看看他的源代码里那块获取了对象锁,比如IO操作,同步方法,同步块等。只要同步了,那么就只有一个线程可以获取对象锁访问当前被同步的对象,其他的线程必须等待。要尽量在关键位置降低或减少这些操作(如,关键位置总是用log4j记很多日志)至于怎么监控线……
造成阻塞的原因为获取对象锁。所以想解决退出阻塞的问题,即使你的设计不能修改,也应该考虑哪块代码频繁获取对象锁,才能解决问题。释放了对象锁,自然就不会有阻塞,而不是所谓的怎样退出阻塞。
suciver 2012-12-17
  • 打赏
  • 举报
回复
引用 1 楼 ticmy 的回复:
如果是别人的封装好的jar包来调用,进入那个方法后就基本不可控了。对于可能存在阻塞的方法,好的API应该提供一个可自定时限或可中断的版本。 直接杀死线程的办法不可取,会导致数据一致性、锁等出现问题
如1楼所说的一般好的API都应该提供设置超时等待解决线程死锁等等的方法。如果实在没有那个就蛋疼了。得去研究它的源码。看看哪些地方容易发生超时或者死锁的地方,如果源码中的方法可以用代理技术解决的话。固然最好。不能的话用javassist去动态的植入代码。不过这个工作量真心不是一般的大,而且难度和复杂度也很高
zxhcloth 2012-12-17
  • 打赏
  • 举报
回复
引用 4 楼 lizhen19870211 的回复:
遇到线程阻塞的问题最好是看看代码中,哪个地方获取了对象锁。即使是在jar也可以看看他的源代码里那块获取了对象锁,比如IO操作,同步方法,同步块等。只要同步了,那么就只有一个线程可以获取对象锁访问当前被同步的对象,其他的线程必须等待。要尽量在关键位置降低或减少这些操作(如,关键位置总是用log4j记很多日志)至于怎么监控线程状态,可以用JProfiler或JConsole进……
在设计时,你这个思路还是不错的,不过在生产环境,少用和多用阻塞并不能解决要退出阻塞的问题。
lizhen19870211 2012-12-17
  • 打赏
  • 举报
回复
遇到线程阻塞的问题最好是看看代码中,哪个地方获取了对象锁。即使是在jar也可以看看他的源代码里那块获取了对象锁,比如IO操作,同步方法,同步块等。只要同步了,那么就只有一个线程可以获取对象锁访问当前被同步的对象,其他的线程必须等待。要尽量在关键位置降低或减少这些操作(如,关键位置总是用log4j记很多日志)至于怎么监控线程状态,可以用JProfiler或JConsole进行监控。 根据你的问题: 1、建议你在关键位置,研究一下怎样少用阻塞,而不是研究怎样退出阻塞。 2、如果代码没问题,线程应该可以很好的协作,不会一直处于阻塞状态。如果代码有问题,代码的瓶颈应该是哪块代码一直获取对象锁,不让其他线程用。
zxhcloth 2012-12-17
  • 打赏
  • 举报
回复
谢谢两位,我也是担心这些问题,所以在安全性很高的场合,我都不敢自己随便开线程。
MiceRice 2012-12-17
  • 打赏
  • 举报
回复
支持下1楼的。 楼主找找开源包的指南说明啥的,如果是比较好的开源包,都会提供:超时 之类的控制机制的。
龙四 2012-12-17
  • 打赏
  • 举报
回复
如果是别人的封装好的jar包来调用,进入那个方法后就基本不可控了。对于可能存在阻塞的方法,好的API应该提供一个可自定时限或可中断的版本。 直接杀死线程的办法不可取,会导致数据一致性、锁等出现问题

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧