JAVA多线程之线程的挂起与恢复(suspend方法与resume方法)

一,介绍

本文讨论JAVA多线程中,使用 thread.suspend()方法暂停线程,使用 thread.resume()恢复暂停的线程 的特点。

先介绍二个关于线程的基本知识:

①线程的执行体是run()方法里面的每一条语句,main线程执行的则是main()方法里面的语句。

②Thread.sleep()方法 使当前正在执行的线程睡眠。

 

二,suspend()方法

①当某个线程的suspend()方法被调用时,该线程会被挂起。如果该线程占有了锁,则它不会释放锁。即,线程在挂起的状态下还持有锁。

②suspend()已经是一个过时的方法了。

来分析一段代码:

复制代码
public class MyThread extends Thread {

    private long i = 0;

    public long getI() {
        return i;
    }

    public void setI(long i) {
        this.i = i;
    }

    @Override
    public void run() {
        while (true) {
            i++;
            System.out.println(i);//同步方法
        }
    }

}            
复制代码

 

复制代码
 1 public class Run {
 2 
 3     public static void main(String[] args) {
 4 
 5         try {
 6             MyThread thread = new MyThread();
 7             thread.start();//启动一个线程'thread'
 8             Thread.sleep(1000);//使当前线程(main线程)睡眠
 9             thread.suspend();//挂起线程'thread'
10             System.out.println("main end!");
11         } catch (InterruptedException e) {
12             e.printStackTrace();
13         }
14     }
15 
16 }
复制代码

在第8行,睡眠的线程是main线程。这样第7行启动的线程'thread'就有机会获得CPU执行,于是:MyThread类的run()方法中的代码就执行了。

当main线程睡眠了1秒钟并重新获得了CPU执行时,执行到第9行。

在第9行,让 第7行中启动的线程 suspend(挂起)。

于是,'thread'线程就不会再打印i的值了。然后,main线程继续执行到第10行,准备打印"main end!"

但是,由于System.out.println(...),它是一个同步方法,PrintOut的println(Object o)的源代码如下:

复制代码
 1  /**
 2      * Prints an Object and then terminate the line.  This method calls
 3      * at first String.valueOf(x) to get the printed object's string value,
 4      * then behaves as
 5      * though it invokes <code>{@link #print(String)}</code> and then
 6      * <code>{@link #println()}</code>.
 7      *
 8      * @param x  The <code>Object</code> to be printed.
 9      */
10     public void println(Object x) {
11         String s = String.valueOf(x);
12         synchronized (this) {
13             print(s);
14             newLine();
15         }
16     }
复制代码

可以看出,在第12行,需要先获得当前PrintOut对象的锁。

而由于此时,MyThread类的线程'thread'是挂起的。它的run()方法里面也有打印语句。因此,它占有的PrintOut的对象锁没有释放。

从而导致main线程无法执行Run.java中的第10行,打印输出语句。

 

注意 PrintOut是System类中的一个静态属性,System类中只有唯一的一个PrintOut对象,System类中相关源代码如下:

复制代码
 /**
     * The "standard" output stream. This stream is already
     * open and ready to accept output data. Typically this stream
     * corresponds to display output or another output destination
     * specified by the host environment or user.
     * <p>
     * For simple stand-alone Java applications, a typical way to write
     * a line of output data is:
     * <blockquote><pre>
     *     System.out.println(data)
     * </pre></blockquote>
     * <p>
     * See the <code>println</code> methods in class <code>PrintStream</code>.
     */
    public final static PrintStream out = null;
复制代码

 

三,resume()方法

该方法很功能很简单,就是恢复 因suspend()方法挂起的线程,使之重新能够获得CPU执行。

 

posted @   大熊猫同学  阅读(14227)  评论(0)    收藏  举报
编辑推荐:
· 当数据爆炸遇上SQL Server:优化策略全链路解析
· 记录一次线上问题排查:JDK序列化问题
· 微服务之间有哪些调用方式?
· 记一次SQL隐式转换导致精度丢失问题的排查
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
阅读排行:
· 一个基于 C# Unity 开发的金庸群侠传 3D 版,直呼牛逼!
· SQL Server 2025 中的改进
· 向商界大佬一样管理技术工作 - 以团队换将+技术重构为例
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析(三)--一个综合的例子
· Qwen3接入评测,最强开源模型更懂Graph了吗?
点击右上角即可分享
微信分享提示