簡體   English   中英

多線程鎖方法

[英]Multi threading lock methods

例 1)

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

例 2)

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++;
        }
    }
}

我從 java 網站獲得了這兩個 java 代碼,但我不清楚這兩者之間的區別。 你們能否給出更多解釋我應該互換使用哪種情況? 提前致謝

有兩個區別:

  • 第一個示例鎖定this而不是私有引用。 我一般認為這是一個壞主意——這意味着其他代碼可能鎖定在同一個監視器上,這使得你的代碼更難推理。 除非您希望其他代碼能夠在同一監視器上獲得鎖定(在這種情況下,我通常會為此目的顯式公開監視器),為什么要讓自己受制於其他代碼呢? 在大多數情況下,鎖應該是一個實現細節,但將其設為公共引用( this很有效)會使該實現細節對世界可見。
  • 第二個示例顯示了在同一 class 中鎖定不同引用的兩種方法。 這意味着兩個線程可以同時調用inc1inc2 如果第一個示例中有多個方法,所有方法都鎖定在this上,那么一次只有一個線程可以進入這些方法中的任何一個。

I typically use a single lock for everything within a single class unless I have good reason to believe that there are going to be lots of independent operations working on only part of the state of the class - in which case that suggests the class may be too大開始。

我還將我的“鎖定變量”設為最終變量,因為您幾乎不想在object的生命周期內更改它們。

因此,如果我真的想使用鎖,我可能最終會將第二個示例編寫為:

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private final Object lock = new Object();

    public void inc1() {
        synchronized(lock) {
            c1++;
        }
    }

    public void inc2() {
        synchronized(lock) {
            c2++;
        }
    }
}

但是,我也會考慮:

  • 不使實例方法從線程安全開始。 我發現從多個線程同時使用 class 的單個實例是相對罕見的。 (靜態方法通常應該是線程安全的。)
  • 使用AtomicLong而不是鎖定。 通常使用更高級別的概念而不是線程原語可以使您的代碼更易於理解更高效。

在第一個示例中,您在this object(實際的 class object 上進行同步。這在大多數情況下就足夠了,將其視為粗粒度鎖。

在第二個示例中,您鎖定創建的對象的唯一目的是鎖定。 這種方法允許您對鎖定進行更精細的控制(在這種情況下,有兩個鎖同時運行,class object 不會被鎖定)

此外,如果您synchronize一個方法,它與在this object 上同步幾乎相同。 基本上它們是可以互換的,但您可能更喜歡一個基於您的鎖定控制情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM