• 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执行。

  • 相关阅读:
    DataGridView编辑后立即更新到数据库的两种方法
    Azure 意外重启, 丢失sql server master表和 filezilla
    欧洲美食精选-德国篇
    Azure 负载均衡和可用性集
    windows Azure 域名绑定
    Azure billing 分析(2)
    Azure billing 分析
    试用windows Azure
    Excel公式无法重算,暂无法解决
    iphone 语音备忘录 同步问题
  • 原文地址:https://www.cnblogs.com/hapjin/p/5449667.html
Copyright © 2020-2023  润新知