天天看點

Java多線程之線程的挂起與恢複(Suspend/Resume)

轉載自http://www.linuxidc.com/Linux/2016-05/131103.htm

一,介紹

本文讨論Java多線程中,使用 thread.suspend()方法暫停線程,使用 thread.resume()恢複暫停的線程的特點。

先介紹二個關于線程的基本知識:

①線程的執行體是run()方法裡面的每一條語句,main線程執行的則是main()方法裡面的語句。

②Thread.sleep()方法 使目前正在執行的線程睡眠。

二,suspend()方法

①當某個線程的suspend()方法被調用時,該線程會被挂起。如果該線程占有了鎖,則它不會釋放鎖。即,線程在挂起的狀态下還持有鎖。

②suspend()已經是一個過時的方法了。

來分析一段代碼:

public class MyThread extends Thread {

    private long i = ;

    public long getI() {
        return i;
    }

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

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

}

------------------------------------------------

  public class Run {  
    public static void main(String[] args) {
 
        try {
            MyThread thread = new MyThread();
            thread.start();//啟動一個線程'thread'
 Thread.sleep();//使目前線程(main線程)睡眠
            thread.suspend();//挂起線程'thread'
            System.out.println("main end!");
        } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
 
 }
           

在第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)的源代碼如下:

/**
 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      */
     public void println(Object x) {
         String s = String.valueOf(x);
         synchronized (this) {
             print(s);
             newLine();
         }
     }
           

可以看出,在第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執行。