synchronized方法可以被中断
我们常说synchronized不可以被中断,并不指synchronized方法不可中断,比如:
public class InterruptSynMethodTest {
public synchronized void foo() throws InterruptedException {
System.out.println("foo begin");
for (int i =0; i < 100; ++i) {
System.out.println("foo ...");
Thread.sleep(1000);
}
}
public static void main(String[] args) {
InterruptSynMethodTest it = new InterruptSynMethodTest();
ExecutorService es = Executors.newCachedThreadPool();
es.execute(() -> {
try {
it.foo();
} catch (InterruptedException e) {
System.out.println("foo is interrupted, msg=" + e.getMessage());
}
});
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
es.shutdownNow();
System.out.println("Main end");
}
}
synchronized方法foo就可以被中断,执行结果为:
foo begin
foo ...
foo ...
foo ...
Main end
foo is interrupted, msg=sleep interrupted
synchronized等待不可中断
synchronized不可以被中断,指的是synchronized等待不可中断,比如:
public class InterruptTest {
public synchronized void foo1() {
System.out.println("foo1 begin");
for (int i =0; i < 5; ++i) {
System.out.println("foo1 ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("foo1 sleep is interrupted, msg=" + e.getMessage());
}
}
}
public synchronized void foo2() throws InterruptedException {
System.out.println("foo2 begin");
for (int i =0; i < 100; ++i) {
System.out.println("foo2 ...");
Thread.sleep(1000);
}
}
public static void main(String[] args) {
InterruptTest it = new InterruptTest();
ExecutorService es = Executors.newCachedThreadPool();
es.execute(() -> it.foo1());
es.execute(() -> {
try {
it.foo2();
} catch (InterruptedException e) {
System.out.println("foo2 is interrupted, msg=" + e.getMessage());
}
});
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
es.shutdownNow();
System.out.println("Main end");
}
}
foo2的synchronized在等待foo1时不可被中断,只有在foo2拿到锁之后才可被中断,执行结果为:
foo1 begin
foo1 ...
foo1 ...
foo1 ...
Main end
foo1 sleep is interrupted, msg=sleep interrupted
foo1 ...
foo1 ...
foo2 begin
foo2 ...
foo2 is interrupted, msg=sleep interrupted
什么情况下可被中断?
根据Java文档,判断方法很简单:只要调用的方法抛出InterruptedException异常,那么它就可以被中断;不抛出InterruptedException的方法是不可中断的。比如如上的foo1方法就不可被中断,foo2方法可被中断。
参考: