1. 程式人生 > >18、使用程式碼塊解決synchronized方法無限等待的問題

18、使用程式碼塊解決synchronized方法無限等待的問題

使用同步方法的過程中容易 造成無限期等待的問題,可以使用同步程式碼塊來解決。

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釋放鎖,他們拿到的不是同一個物件鎖,這樣可以避免使用同步方法造成無限期等待的問題。