1.8 線程暫停
1.8.2 suspend()方法的獨佔行爲
可以用Thread對象的suspend()以及resume()方法,但是這兩種方法是獨佔同步對象的。
public class Thread_182_1 {
static class SynchronizedObject{
synchronized public void printSome(){
System.out.println("begin-->");
if(Thread.currentThread().getName().equals("a")){
System.out.println("a線程被suspend了!");
Thread.currentThread().suspend();
}
System.out.println("end");
}
}
public static void main(String[] args) {
try{
final SynchronizedObject object1 = new SynchronizedObject();
Thread thread1 = new Thread(){
public void run(){
object1.printSome();
}
};
thread1.setName("a");
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread(){
public void run(){
System.out.println("thread2啓動了,但進入不了printSome()方法,因爲被線程a鎖定並且a被掛起了");
object1.printSome();//卡在了這裏
System.out.println("thread2的printSome啓動了");
}
};
thread2.start();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
輸出爲:
begin–>
a線程被suspend了!
thread2啓動了,但進入不了printSome()方法,因爲被線程a鎖定並且a被掛起了
因爲前面的printSome()是同步方法,線程a 沒有釋放該鎖,所以卡在了註釋行
public class Thread_182_2 {
static class MyThread extends Thread{
private long i=0;
public void run(){
while(true){
i++;
}
}
}
public static void main(String[] args) {
try{
MyThread thread = new MyThread();
thread.start();
Thread.sleep(1000);
thread.suspend();
System.out.println("main end");
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
輸出爲:
main end
其中thread被掛起。
但是如果把MyThread改爲:
static class MyThread extends Thread{
private long i=0;
public void run(){
while(true){
i++;
System.out.println(i);
}
}
}
則輸出爲:
115332
115333
115334
115335
115336
也是因爲suspend()不釋放鎖,而println() 方法的源碼中是同步代碼塊
public void println(long x) {
synchronized (this) {
print(x);
newLine();
}
}
最後要說的,suspend()方法已經過時了。
1.8.3 suspend與resume方法的缺點——不同步
一般是因爲suspend()用法出現錯誤,錯誤的掛起導致不同步。
public class Thread_183 {
static 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 printInfo(){
System.out.println(username+"--"+password);
}
}
public static void main(String[] args) throws InterruptedException {
final MyObject myObject = new MyObject();
Thread thread1 = new Thread(){
public void run(){
myObject.setValue("a","aa");
};
};
thread1.setName("a");
thread1.start();
Thread.sleep(500);
Thread thread2 = new Thread(){
public void run(){
myObject.printInfo();
}
};
thread2.start();
}
}
輸出爲:
停止a線程!
a–11
因爲前面的方法中在完成設置username後進行了判斷,如果是線程a就掛起,然後後面的this.password =p就不能執行了。