黑马程序员技术交流社区
标题:
多线程中有关interrupt(),interrupted(),isInterrupted()方法的问题
[打印本页]
作者:
付玉光
时间:
2013-2-26 12:59
标题:
多线程中有关interrupt(),interrupted(),isInterrupted()方法的问题
本帖最后由 付玉光 于 2013-3-8 15:49 编辑
师哥师姐们,在帮小兄我一个大帮呀,自我感觉多线程这块真费解!
①wait(),notify(),notifyAll()都是操作线程的方法,为什么不定义在Thread类中,而定义在Object中呢?
②interrupt(),interrupted(),isInterrupted()这三个方法有什么区别和联系呀?仅仅一个静态的interrupted()方法就让我很挠头了!{:soso_e100:}
作者:
杜鹏飞
时间:
2013-2-26 14:12
本帖最后由 Pf_D 于 2013-2-26 14:13 编辑
多线程非一日之功,其所涉及的是一门学科,即Parallel Computatio。Jeffrey在其书《Windows Internal》中曾说他自上世纪九十年代开始写多线程程序,直到完成这本书时尚不能说自己写多线程程序可以确保无误。
每个函数的作用无法具体说明,文档中对此也是模模糊糊(楼主可以去看java.lang中的thread一节)
问题1
小生接触Java的时间较短,暂时无法替楼主解决。
问题2
void interrupt()
Interrupts this thread.
static boolean interrupted()
Tests whether the current thread has been interrupted
boolean isInterrupted()
Tests whether this thread has been interrupted.
以上的this均指的是主调线程!
作者:
孙传磊
时间:
2013-2-27 12:27
1. 某线程必须获取欲调用实例的锁定,才能调用 wait 方法 notify方法,notifyAll方法。
wait notify notifyAll都是java.lang的Object类的方法,不是Thread类固有的方法。
2.(1)interrupt:置线程的中断状态
(2)isInterrupt:线程是否中断
(3)interrupted:返回线程的上次的中断状态,并清除中断状态
例如: 在 while(!Thread.currentThread().isInterrupted()) {
当达到队列容量时,在这里会阻塞
put的内部会调用LockSupport.park()这个是用来阻塞线程的方法
当其他线程,调用此线程的interrupt()方法时,会设置一个中断标志
LockSupport.part()中检测到这个中断标志,会抛出InterruptedException,并清除线程的中断标志
由于阻塞库函数,如:Object.wait,Thread.sleep除了抛出异常外,还会清除线程中断状态,因此可能在这里要保留线程的中断状态
因此在异常段调用Thread.currentThread().isInterrupted()返回为false
另外,Thread.interrupted()在jdk库的源代码中比较常用,因为它既可以得到上一次线程的中断标志值,又可以同时清除线程的中断标志
若在得到一个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread().interrupt()
作者:
付玉光
时间:
2013-3-7 16:28
本帖最后由 付玉光 于 2013-3-7 16:29 编辑
{:soso_e101:}有时,真郁闷,自己提的问题,自己回答,
关于第一个问题:
①
这些方法都只能存在于同步代码块中,而使用这些方法时必须要标识所属的同步锁,
而同步锁上监视器可以是任意对象,所以任意对象调用的方法一定要定义在object类中,
才符合逻辑呀。
②第二个问题
//从该例中可证明,当前线程调用interrupt()方法并不能使,线程停止。
class MyClass1 extends Thread{
public void run(){
for(int i=1;i<5;i++){
if(i>2)
interrupt();
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args){
MyClass1 my=new MyClass1();
my.start();
}
}
//该例证明:interrupted方法作用:是测试当前线程是否已经中断,线程的中断状态 由该方法清除。
class MyClass2 extends Thread{
public void run(){
try{
for(int i=1;i<5;i++){
System.out.print(i+" ");
if(i>2)
interrupt();
//该句作用:清除中断状态,使程序继续运行。
interrupted();
sleep(1000);
}
}catch(InterruptedException e){
System.out.println("caught");
}
}
public static void main(String[] args){
MyClass2 my=new MyClass2();
my.start();
}
}
//isInterrupt方法的作用是:测试线程是否已经中断,如果已经中断,则返回 true;否则返回 false。
class MyClass3 extends Thread{
public void run(){
int i=0;
try{
//如果中断,则退出循环。
while(!isInterrupted()){
++i;
System.out.println(Thread.currentThread().getName()+" "+i);
if(i>4)
interrupt();
sleep(1000);
}
}catch(InterruptedException e){
System.out.println("结束");
}
}
public static void main(String[] args){
MyClass3 my=new MyClass3();
my.start();
}
}
interrupt方法:它是Thread类中的方法,该方法的作用是:把线程的运行状态改变为中断,
但当对象调用它时,并不用立即让线程停止运行。这点是很多人都不注意,
很多人都认为:线程的中断就是让线程停止.这其实是错误的观点,因为这只是改变了
线程的中断状态,线程并不会立即停止运行,当我们在一个线程对象上调用interrupt()方法,
真正有影响的是wait,join,sleep方法,当然也包括它们的重载方法。
你说的这三个方法都不会抛出InterruptedException,但受影响的wait,join,sleep方法
以即它们的重载形式将会抛出InterruptedException异常。
也就是说,如果一个线程被调用了interrupt()后,它的状态是已中断的.
这个状态对于正在执行wait,join,sleep方法的线程会受到影响,从而抛出中断异常。
为什么调用interrupt方法不会立即使线程停止运行呢?
那是因为多线程的产生目的是提高CPU的利用率(提高处理数据的效率),
但要提高效率(一个更重要)的前提也要保证处理数据的完整性,
给你举个例子,
synchronized void {
x = 3;
y = 4;
}
这个方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到
x = 3;时,被调用了interrupt方法使线程停止了,即使是在同步块中,它也不会执行y=4,
而是直接停止了这样就产生了不完整的残废数据,而这个结果并不是我们想要的,
所以interrupt方法只是改变了线程的中断状态,并不会使线程停止,如果你要非要
使线程在此处停止的话,你可以使用stop方法(该方法是不建议使用的方法,
原因就是因为该方法会使线程产生不完整数据)。
isInterrupt方法的作用是:测试线程是否已经中断,如果已经中断,则返回 true;否则返回 false。
interrupted方法为一个静态方法:它的作用是测试当前线程是否已经中断,线程的中断状态 由该方法清除。
作者:
付玉光
时间:
2013-3-7 16:39
付玉光 发表于 2013-3-7 16:28
有时,真郁闷,自己提的问题,自己回答,
关于第一个问题:
完了,不知道 怎样,把主题,改为《已解决》,,羞死我了。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2