1
lst2008 2018-12-25 11:55:27 +08:00
妥妥的出事
|
3
xiaoidea 2018-12-25 12:50:39 +08:00
我一般用一个 AtomicBoolean 来控制是否继续,然后用带 timeout 的 poll,while(AtomicBoolean.get()) {poll(timeout)}
|
4
SoloCompany 2018-12-25 13:20:44 +08:00 via iPhone
没有任何意义
阻塞位置是 take 语句 interrupt 抛出的是异常 while 判断语句根本捕获不了 还不如 while true 的逻辑清晰 |
6
evanJa OP @SoloCompany 嗯,其实用 while(true)也是一样的
|
7
kanepan19 2018-12-25 14:47:48 +08:00
interrupted 会打断一些重要的操作,如数据库 update 或 insert
while(true){ Object object = waitQueue.poll(5000, TimeUnit.MILLISECONDS); if (object == null && finished && waitQueue.isEmpty()) { // 判断是否结束标准 break; } ... } |
8
kanepan19 2018-12-25 14:50:44 +08:00 1
再看了下标题, 你的情况直接 take 就行,
我上面的伪代码是有个结束开关,结束不要用 interrupted |
10
SilentHill 2018-12-25 16:45:17 +08:00 1
完全没有必要,Thread.interrupted()还会消除掉当前 thread 的 interrupt 标志位,
take 方法内部本身就在 await,如果外部进行 interrupt,那么能够响应并会抛出一个 interruptedException,所以在外部进行 catch,然后决定后续业务怎么处理就可以了。 |
11
dengtongcai 2018-12-25 16:49:33 +08:00
这块你判断中断是出于什么考虑
|
12
evanJa OP @SilentHill @dengtongcai 这个线程是要一直阻塞等待消费消息的,其实本身判断 Thread.interrupted()没什么用,可以用 while(true)代替,我的意思的正常情况下,是否没有显示调用 interrupt 方法,那么这个线程就会一直等待消费消息,因为我只开了这一个线程做消费者( class EventProcessor extends Thread ) 我是想问下这种情况有什么隐患吗?
|
13
SilentHill 2018-12-25 17:49:25 +08:00 2
@evanJa 额,隐患大了去了,假如现在系统要关闭了,这个线程你准备怎么关?
如果使用 running 标志位的方式,你就需要考虑到 blockingdequeue 的 take 方法里面的 await 问题,这个你不主动在外面 interrupt 的话,是会一直阻塞的(除非你 jvm 强行关了)。 正确友好关闭线程的方式是使用 isRunning 之类的标志位,while 的条件就是 while(isRunning), 然后在 take 方法外面捕捉到 inerruptException 后根据业务场景决定是否需要退出线程,万万不可忽视这个异常什么都不做,有时候会导致这个线程一直无法退出。 |
14
leohuachao 2018-12-25 19:05:57 +08:00 via iPhone
可以把 interrupt 理解为线程自身用的一个标志位,表示线程自身的状态,不应该用于业务上的循环判断,应该使用自定义的 isRunning 标志位
|
15
MoHen9 2018-12-25 19:25:02 +08:00 via Android
总结一下楼上的,
1.建议使用 take(),take()方法会阻塞线程,直到有数据时才会再次执行,而且不占用 CPU 资源,还方便 interrupt。 2.使用 while( isRunning),方便平滑结束线程。 楼主这种方式其实一直占着 CPU,不够节约资源。 |
17
evanJa OP @SilentHill 多谢回复,系统关闭了,进程就被杀掉了,这个线程自然就退出了。目的就是不关闭线程,让他一直执行 take 操作
|