MartinYeung
MartinYeung

Love life Love IT IT blog: https://ithelp.ithome.com.tw/users/20119569

Java - Thread-Safety是什麼 - Part 3

閱讀時間: 10分鐘

接上一篇文章,又來為大家在10分鐘內講解一些有關Thread-safety的介紹。

再講多3個做到Thread-safety的方式。

大家可以因應情況選擇一個最合適的表達方法。

7. Synchronized Methods

在同一時間只有一個thread能存取synchronized method,

而其他threads會被阻擋直到第一個thread/之前的thread完成所以任務或者出現例外(exception)。

下面會是一個thread-safe的例子

public synchronized void incrementCounter() {
    counter += 1;
}

首先,在synchronized method的名字前必須有一個synchronized的關鍵字。有了synchronized method,

可以避免多個threads同時存取method。

synchronized method是依賴 內在鎖“intrinsic locks” 或監視鎖 “monitor locks”來完成它的功能。

intrinsic lock是一個與class中特定的實例有關的內在實體。

而在多個threads的環境中,monitor locks只是一個監視角色作為監測不包括的存取情況。

當一個thread使用synchronized method時,它就會獲得一個內在鎖(intrinsic locks)。

在完成了所有任務後,那個thread就會釋放內在鎖(intrinsic locks),允許其他threads來獲得這個內在鎖(intrinsic locks)以存取synchronized method。

大家可以實作同步化在instance methods, static methods 和 statements (synchronized statements)。

8. Synchronized Statements

有時候,當我們只是對於一個segment來進行thread-safe就會有機會出現問題。為了解決及預防,我們可以重新打造incrementCounter() method:

public void incrementCounter() {
    // additional unsynced operationssynchronized(this) {
        counter += 1; 
    }
}

在method內有不同operations,有些要用synchronization,有些是不同的。

針對一些需要用到synchronization的地方,我們可以將那個部分放到synchronized block內。

與synchronized methods不同,synchronized statements必須具體指出物件,

而在這條件下,可以透過使用this reference來滿足。

由於Synchronization的成本高,所以運用了這個方法可以只針對method中的某一部份來做synchronize。

9. Volatile Fields

在一般class中, Class變量的值會被儲存在CPU。

不過由於這個情況會對變量的可見性受到影響,有可能會出現不被其他threads見到的情況。

為了預防這個情況,我們可以使用volatile關鍵字來定義變量。

public class Counter {
 
    private volatile int counter;
 
    // standard constructors / getter
     
}

運用了volatile關鍵字,可以將變量的值直接儲存在主記憶體內。以上的例子就是把counter儲存在主記憶體內。所以當執行這個程序時,它會直接去主記憶體查找而不是在CPU的cache內。而每一次JVM在寫入counter的值時都會直接寫進主記憶體內。

而且運用了volatile關鍵字,可以讓其他thread都能夠在主記憶體內見到所有變量的值。

下面會是一個例子解釋:

public class User {
 
    private String name;
    private volatile int age;
 
    // standard constructors / getters
     
}

每次JVM都會把變量age寫進主記憶體內,但同一時間也會將變量name寫進主記憶體內。因此,這也保證了所有變量的值都會儲存在主記憶體。也可以確保所有threads都能在主記憶體內見到它們的值。


CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…

发布评论