public class TwoThreads {
private static Object resource = new Object();
private static void delay(long n) {
try
{
Thread.sleep(n);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.print("StartMain ");
new Thread1().start();
delay(1000); //dealay 1
Thread t2 = new Thread2();
t2.start();
delay(1000); // delay 2
t2.interrupt(); //here its throwing exception
delay(1000); //delay 3
System.out.print("EndMain ");
}
static class Thread1 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Startl ");
delay(6000);
System.out.print("End1 ");
}
}
}
static class Thread2 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Start2 ");
delay(2000);
System.out.print("End2 ");
}
}
}
}
我在这里感到困惑,为什么{t}在等待获取资源对象上的锁时t2.interrupt()
没有抛出异常而interrupt()
方法可能会抛出安全异常,那么为什么编译器仍允许我们执行它而不放它成了试试阻止。
答案 0 :(得分:2)
同步块不会抛出InterruptedException并在尝试以这种方式获取监视器时中断线程阻塞也无法执行任何操作。
如果你想要这个功能,你需要使用一个lockInterruptibly()的锁,虽然这种情况并不经常使用。
除非当前线程被中断,否则获取锁定。收购 锁如果它没有被另一个线程持有并立即返回, 将锁定保持计数设置为1。
如果当前线程已经保持此锁定,则保持计数为 增加1,方法立即返回。
如果另一个线程持有锁,则当前线程变为 禁用用于线程调度的目的,并且一直处于休眠状态 发生了两件事:
当前线程获取锁定;或其他一些线程 中断当前线程。如果通过当前获取锁定 然后将锁定保持计数设置为1。
如果当前线程: 在进入此方法时设置其中断状态;或是 在获取锁定时被中断,然后是InterruptedException 抛出并清除当前线程的中断状态。
答案 1 :(得分:1)
如果以前的条件都不成立,那么将设置该线程的中断状态。
如果您选中t2.interrupted()
,则会看到true
结果,但线程在进入synchronized
块时阻止,该块不会触发InterruptedException
{1}}。
如果应用程序的环境已经设置了哪些线程可以与其他人交互的限制,那么对interrupt()
的调用可能会抛出SecurityException
,但这并不适用于您的简单示例
答案 2 :(得分:1)
问题尚不清楚,但我想我理解正确,所以我试图回答。
syncrhonized
块 NOT 响应中断。
为此,您可以使用显式锁Lock
,它具有响应中断的方法lockInterruptibly()
。
答案 3 :(得分:0)
java.lang.Thread.interrupt()表示中断此线程。
除非当前线程正在中断(始终允许),否则将调用此线程的 checkAccess 方法,这可能会导致抛出 SecurityException 。
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或者join(),join(long)的方法中阻塞了这个线程, join(long,int),sleep(long)或sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到 InterruptedException 。
你在t2上调用了sleep()。这是获取interruptedException的原因。