惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
NISL@THU
NISL@THU
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
K
Kaspersky official blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
爱范儿
爱范儿
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
S
Securelist
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
美团技术团队
F
Fortinet All Blogs
小众软件
小众软件
Recorded Future
Recorded Future
V
Visual Studio Blog
B
Blog RSS Feed
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
Latest news
Latest news
Spread Privacy
Spread Privacy
H
Heimdal Security Blog

博客园 - frank.net

中国软件工业的冤枉路 随便写写 windows2000实现双机热备份(转) 规范软件开发过程-软件配置管理实践 多线程编程 高级主题(二)注:转 多线程编程 高级主题(一)注:转 多线程编程 秘籍篇(二)注:转 多线程编程 秘籍篇(一)注:转 多线程编程 实践篇(五)注:转 - frank.net - 博客园 多线程编程 实践篇(三)注:转 多线程编程 实践篇(二)注:转 多线程编程 实践篇(一)注:转 多线程编程 基础篇(四)注:转 多线程编程 基础篇(三)注:转 多线程编程 基础篇(二)注:转 多线程编程 基础篇(一)注:转 多线程编程 关于创业方向和项目 Servlet Cookie操作总结
多线程编程 实践篇(四)注:转 - frank.net - 博客园
frank.net · 2008-10-07 · via 博客园 - frank.net

[线程的中断]

不客气地说,至少有一半人认为,线程的"中断"就是让线程停止.
如果你也这么认为,那你对多线程编程还没有入门.

在java中,线程的中断(interrupt)只是改变了线程的中断状态,至于这个中断状态改变后
带来的结果,那是无法确定的,有时它更是让停止中的线程继续执行的唯一手段.不但不是
让线程停止运行,反而是继续执行线程的手段.

对于执行一般逻辑的线程,如果调用调用它的interrupt()方法,那么对这个线程没有任何
影响,比如线程a正在执行:
    while(条件) x ++;
这样的语句,如果其它线程调用a.interrupt();那么并不会影响a对象上运行的线程,如果
在其它线程里测试a的中断状态它已经改变,但并不会停止这个线程的运行.

在一个线程对象上调用interrupt()方法,真正有影响的是wait,join,sleep方法,当然这三个
方法包括它们的重载方法.

请注意:[上面这三个方法都会抛出InterruptedException],记住这句话,下面我会重复.
一个线程在调用interrupt()后,自己不会抛出InterruptedException异常,所以你看到
interrupt()并没有抛出这个异常,所以我上面说如果线程a正在执行while(条件) x ++;
你调用a.interrupt();后线程会继续正常地执行下去.

但是,如果一个线程被调用了interrupt()后,它的状态是已中断的.这个状态对于正在执行
wait,join,sleep的线程,却改变了线程的运行结果.

    一.对于wait中等待notify/notifyAll唤醒的线程,其实这个线程已经"暂停"执行,因为
它正在某一对象的休息室中,这时如果它的中断状态被改变,那么它就会抛出异常.
这个InterruptedException异常不是线程抛出的,而是wait方法,也就是对象的wait方法内部
会不断检查在此对象上休息的线程的状态,如果发现哪个线程的状态被置为已中断,则会抛出
InterruptedException,意思就是这个线程不能再等待了,其意义就等同于唤醒它了.

    这里唯一的区别是,被notify/All唤醒的线程会继续执行wait下面的语句,而在wait
中被中断的线程则将控制权交给了catch语句.一些正常的逻辑要被放到catch中来运行.
    但有时这是唯一手段,比如一个线程a在某一对象b的wait中等待唤醒,其它线程必须
获取到对象b的监视锁才能调用b.notify()[All],否则你就无法唤醒线程a,但在任何线程中可
以无条件地调用a.interrupt();来达到这个目的.只是唤醒后的逻辑你要放在catch中,当然同
notify/All一样,继续执行a线程的条件还是要等拿到b对象的监视锁.

    二.对于sleep中的线程,如果你调用了Thread.sleep(一年);现在你后悔了,想让它早
些醒过来,调用interrupt()方法就是唯一手段,只有改变它的中断状态,让它从sleep中将控制
权转到处理异常的catch语句中,然后再由catch中的处理转换到正常的逻辑.同样,地于join中
的线程你也可以这样处理.

    对于一般介绍多线程模式的书上,他们会这样来介绍:当一个线程被中断后,在进入
wait,sleep,join方法时会抛出异常.
    是的,这一点也没有错,但是这有什么意义呢?如果你知道那个线程的状态已经处于中
断状态,为什么还要让它进入这三个方法呢?当然有时是必须这么做的,但大多数时候没有这么
做的理由,所以我上面主要介绍了在已经调用这三个方法的线程上调用interrupt()方法让它中
这本个方法的"暂停"状态中恢复过来.这个恢复过来就可以包含两个目的:
    一.[可以使线程继续执行],那就是在catch语句中招待醒来后的逻辑,或由catch语句
转回正常的逻辑.总之它是从wait,sleep,join的暂停状态活过来了.
    二.[可以直接停止线程的运行],当然在catch中什么也不处理,或return,那么就完成
了当前线程的使命,可以使在上面"暂停"的状态中立即真正的"停止".