JUC学习
如何正确停止线程?
停止线程应该是一种通知协作的方式,比如interrupt,但是它仅仅是通知线程,线程拥有完全的自主权,根据自身业务来判断什么时候停止,因为如果选择立即停止就可能导致数据不完整这种问题
在休眠状态的线程是否可以感应到中断
可以,程序会抛出一个异常
为什么用 volatile 标记位的停止方法是错误的
停止线程的几种方法:stop(),suspend() 和 resume(),已经被标记为@Deprecated,
stop()直接删除线程状态,暴力停止线程
suspend() 和 resume()配合使用,suspend使当前线程暂停,不销毁线程,还可以恢复,
可能会造成的问题:
使用不当可能会造成公共同步对象被占用,其他线程无法访问,
数据不完整
volatile 这种方法在某些特殊的情况下,比如线程被长时间阻塞的情况,就无法及时感受中断,所以 volatile 是不够全面的停止线程的方法。
那么应该如何正确的停止线程呢:应该使用interrupt请求停止线程,但是如果遇到了InterruptedException怎么办,把异常声明在方法中,使得顶层方法可以感知捕获到异常
wait notify使用注意
-
为什么 wait 方法必须在 synchronized 保护的同步代码中使用?
- 保证“判断-执行”是一个原子操作,保证它在中间不被打断,保证线程安全。如果被打断的话,wait方法并没有执行,但是含有notify的方法执行了,可能会错过notify的唤醒,然后wait方法执行,一直在等待
2. 为什么 wait/notify/notifyAll 被定义在 Object 类中,而 sleep 定义在 Thread 类中?
- 因为java的每个对象都有一个监视器monitor锁,在平常使用过程中我们会获取各种各样的锁,所以wait这种操作锁的方法需要定义在Object类中
- wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求。
- 在同步代码中执行 sleep 方法时,并不会释放 monitor 锁,但执行 wait 方法时会主动释放 monitor 锁。
- sleep 方法中会要求必须定义一个时间,时间到期后会主动恢复,而对于没有参数的 wait 方法而言,意味着永久等待,直到被中断或被唤醒才能恢复,它并不会主动恢复。
- wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法。