说完多线程的等待wait()和唤醒notify(),这里再说一下挂起suspend()和继续执行resume()
package com.zmkj.admin.test;
/**
* 线程的 挂起(suspend) 和 继续执行(resume)
* 这两个操作是一对相对的操作,被挂起的线程必须要等到resume()方法操作后,才能继续执行。
*
* 乍一看,其实和Thread.stop()方法一样,
* 但是,在文档说明中,他们早已被标注为 废弃方法 ,并不推荐使用。
* (其实Thread.stop()方法也是非常不推荐使用的,因为stop 会停止线程的执行,同时释放了锁,那么效果就是方法只执行了一半 可想而知 数据怎么能正确呢)
* (eg:银行转账 A转B 1000块钱,第一步、扣除A 卡中的1000块钱,第二步、B的卡增加1000块钱;如果在第一步执行完的时候 来一个stop()方法,那岂不是银行开心了?A 少一千 ,但是B 并没有到账!!!)
*
* 1、suspend挂起方法在导致线程暂停的同时,并不会释放任何资源。会导致其他线程在访问被他占用的锁的时候无法继续执行。直到resume方法被执行
* 2、如果 resume方法操作意外的在 suspend方法之前就执行了,那么被挂起的线程就可能很难有机会被继续执行。严重的会影响整个系统
* 3、更严重:锁不会释放,而且对于被挂起的线程,从他的线程状态上看,居然还是 Runnable ,这会严重影响我们对系统当前状态的判断。
* 总结为俩字:不推荐使用
*
* @author sunminghao
*/
public class SuspendAndResume {
public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread{
public ChangeObjectThread(String name){
super.setName(name);
}
@Override
public void run() {
synchronized (u){
System.out.println("in " + getName());
Thread.currentThread().suspend();
}
}
}
public static void main(String[] args) throws InterruptedException {
t1.start();
System.out.println("t1 is start ");
Thread.sleep(1000);
System.out.println("t1 sleep is over ");
t2.start();
System.out.println("t2 is start ");
t1.resume();
System.out.println("t1 is resume ");
t2.resume();
System.out.println("t2 is resume ");
//join 方法 https://www.cnblogs.com/skywang12345/p/3479275.html
t1.join();
t2.join();
}
/**
*
* 输出:
* t1 is start
* in t1
* t1 sleep is over
* t2 is start
* t1 is resume
* t2 is resume
* in t2
*
* 从上面的输出我们可以看的出来 是先执行的 t2的resume 后面才执行的 run 方法,所以 可以看到程序不会退出。
*
* 表明两个线程先后进入了临界区,但是程序不会退出,而是会挂起。我们可以使用 jstack 命令打印系统的线程信息 查看
* 这里不再展示,其实查到的就是上面说的 t2 被挂起 线程状态 是 RUNNABLE ;
* t2 被永远挂起,并且永远占用对象 u 的锁。这对系统是致命的。
*/
}
这里虽然说 挂起suspend()和继续执行resume() 不建议使用
那 我们也要研究一下 如果更好的使用,如何规避掉他的弊端
来吧 看看这篇文章
https://blog.csdn.net/qq_34129814/article/details/117307461