暫停執行緒(菜鳥玩執行緒)
阿新 • • 發佈:2018-12-19
暫停執行緒
暫停執行緒,即執行緒還可以恢復執行。
Java多執行緒中,可以使用suspend()方法停止執行緒,使用resume()方法恢復執行緒的執行。
suspend與resume方法的使用
直接上程式碼:
自定義執行緒類
package com.thread9;
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++;
}
}
}
啟動類
package com.thread9;
public class Run {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread. sleep(5000);
//A段
myThread.suspend();
System.out.println("A = " + System.currentTimeMillis() + " , i =" + myThread.getI());
Thread.sleep(5000);
System.out.println("A = " + System.currentTimeMillis() + " , i =" + myThread.getI());
//B段
myThread. resume();
Thread.sleep(5000);
System.out.println("醒了");
//C段
myThread.suspend();
System.out.println("B = " + System.currentTimeMillis() + " , i =" + myThread.getI());
Thread.sleep(5000);
System.out.println("B = " + System.currentTimeMillis() + " , i =" + myThread.getI());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
執行結果
A = 1541211738334 , i =3401982429
A = 1541211743334 , i =3401982429
醒了
B = 1541211748334 , i =6686269724
B = 1541211753334 , i =6686269724
結論
從輸出結果中看,主要看i變數,執行緒的確貝暫停了,而且還可以恢復成執行狀態。
但是執行起來,執行緒結束不了????
suspend與resume方法的缺點——獨佔
如果使用不當,極容易早晨公共的同步物件的獨佔,使得其他執行緒無法訪問公共同步物件。
程式碼例項如下:
自定義執行緒類
package com.thread10;
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);
}
}
}
啟動類
package com.thread10;
public class Run {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(1000);
myThread.suspend();
System.out.println("main end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
執行結果
207532
207533
207534
207535
207536
207537
207538
207539
207540
207541
//此處暫停,不繼續輸出
結論
出現這種情況得原因是,當程式執行到println()方法內部停止時,同步鎖未被釋放。
導致當前PrintStream物件得println()方法一直呈“暫停”狀態,並且“鎖未釋放”,而main()方法中的程式碼
System.out.println("main end");
遲遲不能執行列印。
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
suspend與resume方法的缺點——不同步
在使用suspend和resume方法時也容易出現因為執行緒的暫停而導致資料不同步的情況,如下:
自定義共享變數類
package com.fiberhome.thread11;
public class MyObject {
private String username = "1";
private String password = "11";
public void setValue(String u, String p) {
this.username = u;
if (Thread.currentThread().getName().equals("a")) {
System.out.println("停止a執行緒!");
Thread.currentThread().suspend(); //執行緒停止
}
this.password = p;
}
public void printUsernamePassword() {
System.out.println(username + " " + password);
}
}
啟動類
package com.fiberhome.thread11;
public class Run {
public static void main(String[] args) throws InterruptedException {
//共享變數
final MyObject myObject = new MyObject();
//執行緒1
Thread thread1 = new Thread() {
@Override
public void run() {
myObject.setValue("a", "aa");
}
};
thread1.setName("a");
thread1.start();
Thread.sleep(500);
//執行緒2
Thread thread2 = new Thread() {
@Override
public void run() {
myObject.printUsernamePassword();
}
};
thread2.start();
}
}
執行結果
停止a執行緒!
a 11
結論
從輸出結果看,共享物件資料沒有同步。如果同步,輸出結果應該為 a aa