文章22 | 阅读 7592 | 点赞0
在测试中断异常前我们先了解一下 sleep 和 wait 的本质区别:sleep 不会释放同步锁,wait 会释放同步锁。
抛出中断异常后会释放同步锁。
测试代码如下:
public class Sleep {
public static void main(String[] args) {
Object o = new Object();
Thread t = new Thread(() -> {
synchronized (o) {
try {
System.out.println("t start");
TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
System.out.println("t end");
} catch (InterruptedException e) {
System.out.println("t interrupted......");
}
}
});
t.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
}
}
控制台输出如下:
t1 start
t1 interrupted......
测试代码如下:
public class Sleep {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Thread t = new Thread(() -> {
try {
lock.lock();
System.out.println("t start");
TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
System.out.println("t end");
} catch (InterruptedException e) {
System.out.println("t interrupted......");
} finally {
lock.unlock();
}
});
t.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
}
}
控制台输出如下:
t start
t interrupted......
由以上两个测试我们可以得知:线程在通过 sleep 方法进入超时等待状态时是可以响应中断的。
使用 wait 方法同样可以响应中断。
使用 join 方法后同样可以响应中断。
当前线程调用 join 方法也可以阻塞当前线程本身,测试代码如下:
public class Join {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
System.out.println("1");
System.out.println("1");
try {
Thread.currentThread().join(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1");
System.out.println("1");
System.out.println(System.currentTimeMillis());
}
}
控制台输出如下:
1608960108281
1
1
1
1
1608960113282
对于 synchronized 来说,阻塞状态下是无法响应中断的,对于 lock 来说,调用 lock()
方法进入阻塞状态后同样无法响应中断,但 lock 提供了另一个方法可以用来响应中断:lockInterruptibly()
。
synchronized 测试代码如下:
public class Test {
public static void main(String[] args) {
Object o = new Object();
Thread t1 = new Thread(() -> {
synchronized (o) {
try {
System.out.println("t1 start");
TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
System.out.println("t1 end");
} catch (InterruptedException e) {
System.out.println("t1 interrupted");
}
}
});
t1.start();
Thread t2 = new Thread(() -> {
synchronized (o) {
try {
System.out.println("t1 start");
TimeUnit.SECONDS.sleep(5);
System.out.println("t1 end");
} catch (InterruptedException e) {
System.out.println("t1 interrupted");
}
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();
}
}
控制台输出如下:
t1 start
lock()
测试代码如下:
public class T04_ReentrantLock4 {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
try {
lock.lock();
System.out.println("t1 start");
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
System.out.println("t1 end");
} catch (InterruptedException e) {
System.out.println("t1 Interrupted......");
} finally {
lock.unlock();
}
});
t1.start();
Thread t2 = new Thread(() -> {
try {
lock.lock();
// lock.lockInterruptibly();
System.out.println("t2 start");
TimeUnit.SECONDS.sleep(5);
System.out.println("t2 end");
} catch (InterruptedException e) {
System.out.println("t2 Interrupted......");
} finally {
// 这里不加 lock.unlock(); 是因为当前线程根本没有获取锁,中断异常被 catch 捕获前肯定要先执行 finally 里的代码,但没有获取锁就释放锁是会抛异常的,不信你可以试试
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();
}
}
控制台输出如下:
t1 start
线程 t2 由于没有获取对象锁,所以进入阻塞状态,无法响应中断。
我们再来看看另一种测试方法,lockInterruptibly()
代码如下:
public class T04_ReentrantLock4 {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
try {
lock.lock();
System.out.println("t1 start");
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
System.out.println("t1 end");
} catch (InterruptedException e) {
System.out.println("t1 Interrupted......");
} finally {
lock.unlock();
}
});
t1.start();
Thread t2 = new Thread(() -> {
try {
// lock.lock();
lock.lockInterruptibly();
System.out.println("t2 start");
TimeUnit.SECONDS.sleep(5);
System.out.println("t2 end");
} catch (InterruptedException e) {
System.out.println("t2 Interrupted......");
} finally {
// 这里不加 lock.unlock(); 是因为当前线程根本没有获取锁,中断异常被 catch 捕获前肯定要先执行 finally 里的代码,但没有获取锁就释放锁是会抛异常的,不信你可以试试
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();
}
}
控制台输出如下:
t1 start
t2 Interrupted......
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41685207/article/details/111738796
内容来源于网络,如有侵权,请联系作者删除!