亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java同步方法鎖定對象,還是方法?

Java同步方法鎖定對象,還是方法?

繁花不似錦 2019-10-14 11:01:29
如果我在同一個類中有2個同步方法,但是每個方法都訪問不同的變量,那么2個線程可以同時訪問這2個方法嗎?鎖是否發生在對象上,或者是否與同步方法中的變量一樣具體?例:class X {    private int a;    private int b;    public synchronized void addA(){        a++;    }    public synchronized void addB(){        b++;    }}2個線程可以訪問類X執行相同的實例x.addA(),并x.addB()在同一時間?
查看完整描述

3 回答

?
四季花海

TA貢獻1811條經驗 獲得超5個贊

如果將方法聲明為已同步(就像通過鍵入所做的那樣public synchronized void addA()),則會在整個對象上進行同步,因此,從同一對象訪問不同變量的兩個線程將始終相互阻塞。


如果您一次只想同步一個變量,那么兩個線程在訪問不同變量時不會互相阻塞,您可以分別以synchronized ()塊同步。如果a和b是對象引用,則可以使用:


public void addA() {

    synchronized( a ) {

        a++;

    }

}


public void addB() {

    synchronized( b ) {

        b++;

    }

}

但是由于它們是原始類型,所以您不能這樣做。


我建議您改用AtomicInteger:


import java.util.concurrent.atomic.AtomicInteger;


class X {


    AtomicInteger a;

    AtomicInteger b;


    public void addA(){

        a.incrementAndGet();

    }


    public void addB(){ 

        b.incrementAndGet();

    }

}


查看完整回答
反對 回復 2019-10-14
?
largeQ

TA貢獻2039條經驗 獲得超8個贊

為此,在方法聲明上同步的是語法糖:


 public void addA() {

     synchronized (this) {

          a++;

     }

  }

在靜態方法上,它是語法糖:


 ClassA {

     public static void addA() {

          synchronized(ClassA.class) {

              a++;

          }

 }

我認為,如果Java設計人員知道了現在對同步的了解,他們將不會添加語法糖,因為它經常會導致并發的不良實現。


查看完整回答
反對 回復 2019-10-14
?
九州編程

TA貢獻1785條經驗 獲得超4個贊

從“ Java?教程”中的同步方法開始:


首先,不可能對同一對象的兩次同步方法調用進行交織。當一個線程正在執行對象的同步方法時,所有其他調用同一對象塊的同步方法的線程(掛起執行),直到第一個線程對該對象完成。


在同步塊上的“ Java?教程”中:


同步語句對于通過細粒度同步提高并發性也很有用。例如,假設類MsLunch有兩個實例字段c1和c2,它們從未一起使用。這些字段的所有更新都必須同步,但是沒有理由阻止c1更新與c2更新交織 —這樣做會通過創建不必要的阻塞來減少并發性。代替使用同步方法或以其他方式使用與此關聯的鎖,我們僅創建兩個對象來提供鎖。


(強調我的)


假設您有2個非交織變量。因此,您希望同時從不同的線程訪問每個線程。您需要定義鎖不上對象類本身,而是對類對象像下面(例如,從第二個Oracle鏈接):


public class MsLunch {


    private long c1 = 0;

    private long c2 = 0;


    private Object lock1 = new Object();

    private Object lock2 = new Object();


    public void inc1() {

        synchronized(lock1) {

            c1++;

        }

    }


    public void inc2() {

        synchronized(lock2) {

            c2++;

        }

    }

}


查看完整回答
反對 回復 2019-10-14
  • 3 回答
  • 0 關注
  • 863 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號