一,介紹
本文討論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執行。