当前位置: 代码迷 >> J2SE >> 另一个关于Thread的有关问题
  详细解决方案

另一个关于Thread的有关问题

热度:87   发布时间:2016-04-24 00:45:33.0
另一个关于Thread的问题
首先请各位放心,我会结贴的,发帖比较少,有两个(包括这个)正在解答的帖子没结,致使结贴率比较低(因为一共才发了5个帖子,算上这个)。(刚才有人说我结贴率低,不想回答我的问题)

java核心技术有一段这么说(别担心,后面我会翻译的):The isInterrupted check is neither necessary nor useful if you call the sleep method
(or another interruptible method) after every work iteration. If you call the sleep
method when the interrupted status is set, it doesn’t sleep. Instead, it clears the
status (!) and throws an InterruptedException. Therefore, if your loop calls sleep, don’t
check the interrupted status. Instead, catch the InterruptedException, like this:
public void run()
{
try
{
. . .
while (more work to do)
{
do more work
Thread.sleep(delay);
}
}
catch(InterruptedException e)
{
// thread was interrupted during sleep
}
finally
{
cleanup, if required
}
// exiting the run method terminates the thread
}


翻译过来大致就是,如果你在循环中调用thread的sleep()方法(或者其他可打断的方法),那么在循环头部利用isInterrupted()方法检测“打断位”是否被设置是没有必要而且没用的。因为如果打断位被设置了,sleep不会执行,它会清除打断位,并且抛出interruptedexception异常。所以,在循环中调用sleep的话,不要检测isInterrupted,而要捕获异常。

我想问,在循环中调用sleep(),循环就不能检测isInterrupted了吗?
我要是这样写:
while (!Thread.currentThread().isInterrupted() && more work to do)
如果打断位已经被设置,已经不会继续执行循环体了啊,而如果写成
while (more work to do)
是不会管打断位被没被设置,都会执行循环体。

另外,后者如果在打断位被设置的情况下,是以异常结束的,而前者直接跳过循环体,不抛出异常。
当让,如果循环头部检测时,打断位未被设置,而在循环体执行过程中被其他线程设置,二者是相同的。

写的比较凌乱,希望高手解答。
最后再次重申,我会结贴的!原因看开头!
谢谢!

------解决方案--------------------
http://hi.baidu.com/bskyzh/blog/item/3091eaedddb41a2e63d09f64.html
参考一下这个。
------解决方案--------------------
就看LZ你怎么中断线程了,如果是调用interrupt中断,那么该方法的javadoc里已经清楚地说明了

interrupt
public void interrupt()中断线程。 
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。 

如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 

如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。 

如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。 

如果以前的条件都没有保存,则该线程的中断状态将被设置。

中断一个不处于活动状态的线程不需要任何作用。 


抛出: 
SecurityException - 如果当前线程无法修改该线程

红色部分,说明了LZ的问题,此时,中断状态被清空了,所以isInterrupted是返回false的

------解决方案--------------------
哦。楼主翻译的那个意思。
可以换一个角度来理解,就会明白了。
Java code
while(more work to do){ try{  do more work  Thread.sleep(delay); }catch(Exception e){  // thread was interrupted during sleep }}
------解决方案--------------------
哎。。。

这段代码意思很明确了

Java code
while(more work to do){ try{  do more work  Thread.sleep(delay); }catch(Exception e){  // thread was interrupted during sleep }}
  相关解决方案