t.interrupt() 问题

jn0115 2014-05-30 10:56:27
线程对象调用interrupt(),如果该对象处在wait,join,sleep将会触发InterruptedException。
但是这个InterruptedException到底是谁抛出的,因为线程处在阻塞状态下,如果还未获得锁,自己不可能抛出异常才对。
下面的代码貌似也说明这点,但是问题来了:如果这种情况下不能抛出异常,那么如何中断Thread1 , 因为锁对象synObj 被Thread2永久持有。


public class InterruputTest {
public static volatile int flag = 10;
public static Object synObj = new Object();

public static void main(String[] args) throws InterruptedException {

Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();

t1.start();
t2.start();

Thread.sleep(1000);
t1.interrupt();

}


static class Thread1 extends Thread {
public void run(){
synchronized (synObj) {
while(flag>=10){
try {
synObj.wait();
} catch (InterruptedException e) {

flag = 1;
System.out.println("Thread1 has been interrupted!");
}
}
}

}
}


static class Thread2 extends Thread {
public void run(){
synchronized (synObj) {
while(true){
if(flag<10){
System.out.println("flag=" + flag);
}
flag=10;
}
}

}
}

}
...全文
217 2 打赏 收藏 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
lymoge 2014-05-31
  • 打赏
  • 举报
回复
Thread1 running. Thread2 running Interrupt Thread1. Thread2 running thread1.isInterrupted()true Thread2 running Thread2 running Thread2 running Thread2 running Thread2 running Thread2 running Thread2 running Thread2 running Thread2 end. wait interrupted,isInterrupted=false thread1.isInterrupted()false Thread1 running. Thread1 running. Thread1 running. Thread1 running. Thread1 running. Thread1 running. Thread1 running. Thread1 running. Thread1 running.
lymoge 2014-05-31
  • 打赏
  • 举报
回复
刚对线程有些研究,Thread2没有自己中断的可能无法释放锁所以应该是死锁了,只能强制终止。调用thread1的interrupt方法可以改变线程的中断状态,但是由于没有获得锁无法抛出InterruptedException异常。就像notify一样,只有退出同步块放弃了锁才能唤醒一个等待的线程。个人观点,可能有误。 测试的代码:

public class Interrupt {
    Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        new Interrupt().foo();
    }

    Thread thread1;
    Thread thread2;

    private void foo() throws InterruptedException {
        thread1 = new Thread1();
        thread2 = new Thread2();
        thread1.start();
        thread2.start();
        new Thread() {
            {
                setDaemon(true);
            }

            @Override
            public void run() {
                boolean b1 = false;
                boolean b2 = false;
                while (true) {
                    if (b1 != (b1 = thread1.isInterrupted()))
                        System.out.println("thread1.isInterrupted()" + thread1.isInterrupted());

                    if (b2 != (b2 = thread2.isInterrupted()))
                        System.out.println("thread2.isInterrupted()" + thread2.isInterrupted());
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {}
                }
            }
        }.start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {}
        thread2.interrupt();
        // thread2.stop();
    }


    class Thread1 extends Thread {
        @Override
        public void run() {
            boolean once = true;
            synchronized (lock) {
                for (int i = 0; i < 10; i++) {
                    System.out.println("Thread1 running.");
                    if (once) {
                        once = false;
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            System.out.println("wait interrupted,isInterrupted=false");
                        }
                    }
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {}
                }
            }
        }
    }


    class Thread2 extends Thread {
        @Override
        public void run() {
            boolean once = true;
            synchronized (lock) {
                while (true) {
                    System.out.println("Thread2 running");
                    try {
                        Thread.sleep(500);
                        if (once) {
                            once = false;
                            System.out.println("Interrupt Thread1.");
                            thread1.interrupt();
                            // lock.notify();
                        }
                    } catch (InterruptedException e) {
                        System.out.println("Thread2 end.");
                        return;
                    }
                }
            }
        }
    }
}

62,620

社区成员

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

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