这是一个来自 Java 编程思想的例子,它只是想表达 sleep 的线程可中断,但同步 IO 等待资源,或同步获得锁失败的线程,是不可同步的。

//: concurrency/Interrupting.java

// Interrupting a blocked thread.

import java.util.concurrent.*;

import java.io.*;

import static net.mindview.util.Print.*;

class SleepBlocked implements Runnable {

public void run() {

try {

TimeUnit.SECONDS.sleep(100);

} catch(InterruptedException e) {

print("InterruptedException");

}

print("Exiting SleepBlocked.run()");

}

}

class IOBlocked implements Runnable {

private InputStream in;

public IOBlocked(InputStream is) { in = is; }

public void run() {

try {

print("Waiting for read():");

in.read();

} catch(IOException e) {

if(Thread.currentThread().isInterrupted()) {

print("Interrupted from blocked I/O");

} else {

throw new RuntimeException(e);

}

}

print("Exiting IOBlocked.run()");

}

}

class SynchronizedBlocked implements Runnable {

public synchronized void f() {

while(true) // Never releases lock

Thread.yield();

}

public SynchronizedBlocked() {

new Thread() {

public void run() {

f(); // Lock acquired by this thread

}

}.start();

}

public void run() {

print("Trying to call f()");

f();

print("Exiting SynchronizedBlocked.run()");

}

}

public class Interrupting {

private static ExecutorService exec =

Executors.newCachedThreadPool();

static void test(Runnable r) throws InterruptedException{

Future> f = exec.submit(r);

TimeUnit.MILLISECONDS.sleep(100);

print("Interrupting " + r.getClass().getName());

f.cancel(true); // Interrupts if running

print("Interrupt sent to " + r.getClass().getName());

}

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

test(new SleepBlocked());

test(new IOBlocked(System.in));

test(new SynchronizedBlocked());

test(new Runnable() { //自己写的测试线程

@Override

public void run () {

System.out.println("1 start run");

try {

new Object().wait(); //这句不抛异常,为什么?

} catch (InterruptedException e) {

System.out.println("1 catch InterruptedException");

e.printStackTrace();

}

System.out.println("1 exit run");

}

});

TimeUnit.SECONDS.sleep(3);

print("Aborting with System.exit(0)");

new Object().wait(); //这句抛异常

System.exit(0); // ... since last 2 interrupts failed

}

}

打印结果:

Interrupting SleepBlocked

Interrupt sent to SleepBlocked

InterruptedException

Exiting SleepBlocked.run()

Waiting for read():

Interrupting IOBlocked

Interrupt sent to IOBlocked

Trying to call f()

Interrupting SynchronizedBlocked

Interrupt sent to SynchronizedBlocked

1 start run

Interrupting Interrupting$1

Interrupt sent to Interrupting$1 //而且看起来,中断也没起作用?(如果有作用,之后应该出现这个线程的打印结果)

Aborting with System.exit(0)

Exception in thread "main" java.lang.IllegalMonitorStateException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:502)

at Interrupting.main(Interrupting.java:92)

我知道 wait 正确用法是在同步方法或同步块中使用,

所以现在问题有 2 个,

为啥主函数的 new Object().wait();抛 IllegalMonitorStateException 异常,我自创的线程却没有抛出 IllegalMonitorStateException 异常呢?

从打印结果,我那个线程真的 wait 了(因为只打印出来一句)。但为啥中断它时,还是没有反应呢?

test(new Runnable() {

@Override

public void run () {

synchronized(this) {

System.out.println("1 start run");

try {

wait();

} catch (InterruptedException e) {

System.out.println("1 catch InterruptedException");

e.printStackTrace();

}

System.out.println("1 exit run");

}

}

});

然后我试了上面这个版本的,打印结果如下:

Interrupting SleepBlocked

Interrupt sent to SleepBlocked

InterruptedException

Exiting SleepBlocked.run()

Waiting for read():

Interrupting IOBlocked

Interrupt sent to IOBlocked

Trying to call f()

Interrupting SynchronizedBlocked

Interrupt sent to SynchronizedBlocked

1 start run

Interrupting Interrupting$1

Interrupt sent to Interrupting$1

1 catch InterruptedException

java.lang.InterruptedException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:502)

at Interrupting$1.run(Interrupting.java:75)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

at java.util.concurrent.FutureTask.run(FutureTask.java:266)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

1 exit run

Aborting with System.exit(0)

Exception in thread "main" java.lang.IllegalMonitorStateException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:502)

at Interrupting.main(Interrupting.java:86)

所以,wait 之前是获得锁的情况,才可以被中断呗?

java 同步块 抛出异常_不把 wait 放在同步块中,为啥这种情况不会抛出 IllegalMonitorStateException?...相关推荐

  1. mysql主从同步默认延迟_减少mysql主从数据同步延迟问题的详解

    基于局域网的master/slave机制在通常情况下已经可以满足'实时'备份的要求了.如果延迟比较大,就先确认以下几个因素: 1. 网络延迟 2. master负载 3. slave负载 一般的做法是 ...

  2. 在不丢失堆栈跟踪的情况下重新抛出Java中的异常

    在C#中,我可以使用throw; 保留堆栈跟踪时重新抛出异常的语句: try {... } catch (Exception e) {if (e is FooException)throw; } Ja ...

  3. python3中的int类型占64位_在windows 10 64位计算机中,默认情况下,numpy数组数据类型将以int32形式出现...

    最初的海报Prana问了一个非常好的问题."为什么在64位计算机上,整数默认设置为32位?"在 据我所知,简短的回答是:"因为它的设计是错误的". 显然,64位 ...

  4. setstate是同步还是异步_谈谈 IO模型:同步、异步、阻塞、非阻塞

    同步/异步.阻塞/非阻塞 说的是一回事儿吗? 同步/异步.阻塞/非阻塞 你能通俗易懂的讲清楚吗? Java 中的 BIO.NIO.AIO 你了解吗? Socket 编程你还会吗? Linux 操作系统 ...

  5. 无法同步谷歌日历_真香!自动同步ios的提醒事项和日历,显示日打卡内容

    ios的提醒事项没有日历视图,这是我一直想要的功能,以前一直寻求第三方软件,但是第三方软件都要收费,现在发现通过一个脚本就可以自动同步,于是自己动手写了个脚本. 视频教程请戳 真香!一键同步ios[提 ...

  6. java 对象序列化 数组_序列化-将任何对象转换为j中的字节数组

    您要执行的操作称为"序列化". 有几种方法可以做到,但是如果您不需要花哨的东西,我认为使用标准Java对象序列化就可以了. 也许您可以使用这样的东西? package com.ex ...

  7. raid5通常需要几块盘_为什么RAID5至少需要三块硬盘

    展开全部 这是由Raid 5工作原理决定的.Raid 5磁盘阵列的每块硬盘上,既有数据信息也有校验信息.RAID5建立后,坏掉62616964757a686964616fe58685e5aeb9313 ...

  8. mysql主从同步可靠吗_说一下mysql主从同步

    首先说一下mysql主从复制支持哪些方式: 单向,双向,链式级联,实时,异步复制.在复制的时候,一台服务器充当主服务器,而一个或者多个的其他服务器充当从服务器. 一主一从: 一组多从 互为主从 还有什 ...

  9. 无法同步谷歌日历_关于苹果iCloud备份 | 同步,你要了解这些!

    朋友们小年快乐!今天给大家分享一篇小科普文章,关于苹果的 iCloud 备份以及同步相关的小知识.发完就得去剪辑视频去啦,今天拍摄的是惠威AW-83头戴式无线降噪耳机,下周给大家分享视频.我们回归正题 ...

最新文章

  1. 2022,人工智能开启未来新密码
  2. 找不到命令报错bash:command not found解决方案
  3. 32 墨水屏股票显示器_炒股护眼新选择 | 电子墨水显示器amp;平板盯盘效果(附视频)...
  4. Boost:将自定义占位符_1复制到arg <1>的测试程序
  5. 学习File API用于前端读取文件
  6. Tomcat详解(十)——Tomcat性能调优
  7. 每日一句20191105
  8. 调整计算机硬盘大小,详细教您怎么调整硬盘分区
  9. 宝塔面板ftp空间连接失败解决方案汇总
  10. 罗振宇的跨年演讲《时间的朋友》听课笔记
  11. Latex表格标题左对齐,并且table加粗
  12. 元宇宙产业委一届二次全会召开 同步举办共享大会和全球元宇宙大会
  13. 判断当前是否是移动端H5打开
  14. 《Graph neural networks A review of methods and applications》翻译
  15. Fintech公开课丨黄嵩:数字化转型本质论
  16. canvas绘制一个圆形
  17. 在Euroc MH_05数据集上调试orbslam3并测试的过程
  18. windows10 critical_service_failed解决办法
  19. Bitmap—有损压缩和无损压缩
  20. 城市智慧物业水泵房,消防泵房的解决方案

热门文章

  1. mysql workbench pdm_MySQL Workbench
  2. python调用海康sdk 数据类型
  3. python 生成code128c
  4. poly-YOLOv3
  5. Can't get attribute '_rebuild_tensor_v2' on module 'torch._utils'
  6. CNN网络优化加速汇总
  7. Kd-Tree算法原理和开源实现代码
  8. linux 新开窗口到最前,怎么设置一个窗口总是在电脑桌面的最前
  9. dell服务器 win7系统安装教程,dell官方win7系统64位系统安装教程
  10. oracle如何删除可回收归档,Oracle正确删除归档并回收空间的方法