1. 程式人生 > >Java多執行緒--多個物件多個鎖

Java多執行緒--多個物件多個鎖

上一篇部落格中介紹了多個執行緒同時訪問一個物件,產生一個物件鎖,屬於同步訪問,現在介紹下如果是訪問多個物件,會怎麼執行那?

Demo:

HasSelfPrivateNum類:

public class HasSelfPrivateNum {
    private int num=0;
   synchronized  public void addI(String username){
        try{
            if(username.equals("a")){
                num=100;
                System.out.println("a set over!"
); Thread.sleep(2000); }else{ num=200; System.out.println("b set over!"); } System.out.println(username+" num="+num); }catch (InterruptedException e){ e.printStackTrace(); } } }

執行緒類ThreadA和ThreadB:

public class ThreadA extends Thread {
    private HasSelfPrivateNum numRef;
    public ThreadA (HasSelfPrivateNum numRef){
        super();
        this.numRef=numRef;
    }

    @Override
    public void run(){
        super.run();
        numRef.addI("a");
    }
}
public class ThreadB extends
Thread {
private HasSelfPrivateNum numRef; public ThreadB (HasSelfPrivateNum numRef){ super(); this.numRef=numRef; } @Override public void run(){ super.run(); numRef.addI("b"); } }

Run類,執行Main方法:

public class Run {
    public static void main(String[] args){
        HasSelfPrivateNum numRef1=new HasSelfPrivateNum();
        HasSelfPrivateNum numRef2=new HasSelfPrivateNum();
        ThreadA athread=new ThreadA(numRef1);
        athread.start();
        ThreadB bthread=new ThreadB(numRef2);
        bthread.start();
    }
}

執行結果:

a set over!
b set over!
b num=200
a num=100

例子是兩個執行緒分別訪問同一個類的兩個不同例項的相同名稱的同步方法,效果是以非同步的方式執行的。原因是:示例建立了2個業務物件,在系統中產生了2個鎖,所以執行結果是非同步的,列印的效果是先列印了b,然後列印了a。

HasSelfPrivateNum.java中使用了synchronized關鍵字,但列印的順序卻不是同步的是交叉的,為什麼?

解:
關鍵字 synchronized取得的鎖是物件鎖,而不是把一段程式碼或方法(函式)當做鎖,如果多個執行緒訪問的是多個物件,則JVM會建立多個鎖,互不影響。

番外:
如果在靜態方法上加synchronized關鍵字,表示鎖定類級別的鎖,獨佔class類,這時候多個執行緒訪問的是相同的鎖。