18、使用程式碼塊解決synchronized方法無限等待的問題
阿新 • • 發佈:2018-12-22
使用同步方法的過程中容易 造成無限期等待的問題,可以使用同步程式碼塊來解決。
package com.demo2; public class MyObject { synchronized public void methodA(){ System.out.println("methodA begin"); boolean flag = true; while(flag){ } System.out.println("methodA end"); } synchronized public void methodB(){ System.out.println("methodB begin"); System.out.println("methodB end"); } }
package com.demo2;
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.methodA();
}
}
package com.demo2; public class ThreadB extends Thread { private MyObject myObject; public ThreadB(MyObject myObject) { this.myObject = myObject; } @Override public void run() { myObject.methodB(); } }
package com.demo2; public class Run { public static void main(String[] args) { MyObject myObject = new MyObject(); ThreadA threadA = new ThreadA(myObject); ThreadB threadB = new ThreadB(myObject); threadA.setName("a"); threadB.setName("b"); threadA.start(); threadB.start(); } }
執行結果:
methodA begin
由結果可以看出 methodB一直沒有被呼叫,也就是說執行緒B一直在等待執行緒A釋放物件鎖。對上述程式碼,進行如下修改
package com.demo2;
public class MyObject {
public void methodA(){
synchronized(new Object()){
System.out.println("methodA begin");
boolean flag = true;
while(flag){
}
System.out.println("methodA end");
}
}
public void methodB(){
synchronized(new Object()){
System.out.println("methodB begin");
System.out.println("methodB end");
}
}
}
package com.demo2;
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.methodA();
}
}
package com.demo2;
public class ThreadB extends Thread {
private MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.methodB();
}
}
package com.demo2;
public class Run {
public static void main(String[] args) {
MyObject myObject = new MyObject();
ThreadA threadA = new ThreadA(myObject);
ThreadB threadB = new ThreadB(myObject);
threadA.setName("a");
threadB.setName("b");
threadA.start();
threadB.start();
}
}
執行結果:
methodA begin
methodB begin
methodB end
由結果可以看出,執行緒B無需等待執行緒A釋放鎖,他們拿到的不是同一個物件鎖,這樣可以避免使用同步方法造成無限期等待的問題。