簡體   English   中英

靜態方法和線程安全

[英]static method and thread safety

以下代碼線程是否安全?

    public static Entity getInstance(){
//the constructor below is a default one.
     return new Entity();
    }

假設構造函數本身是線程安全的,那很好。

構造函數不是線程安全的,但可能是非常不尋常的......即使它調用Entity的默認自動生成構造函數,基本構造函數也可能不是線程安全的。 我不是說它可能,只是可能:)

基本上沒有應用於靜態方法實例方法構造函數的魔術線程安全性。 除非同步應用,否則它們可以同時在多個線程上調用。 如果他們不獲取或更改任何共享數據,它們通常是安全的 - 如果他們確實訪問共享數據,則需要更加小心。 (如果共享數據是不可變的或只是讀取,那通常沒問題 - 但是如果其中一個線程要改變它,你需要非常小心。)

只有靜態初始化器(靜態變量的初始化表達式和直接在類中的static { ... }塊)有特殊處理 - VM確保它們只執行一次,阻止等待類型的其他線程初始化。

它取決於Entity構造函數的細節。 如果Entity構造函數修改共享數據,則不是。

它可能是線程安全的,但有什么意義呢? 如果您只是使用工廠方法重定向到默認構造函數,那么為什么不首先使用構造函數? 所以問題是:你想要實現什么目標? 名稱getInstance()建議使用單例(至少是通常的做法),但是你顯然沒有單例。 如果你想要一個單例,請使用這樣的靜態內部持有者類:

    public class Singleton {

        private Singleton() {
        }

        public static Singleton getInstance() {
            return InstanceHolder.INSTANCE;
        }

        private static final class InstanceHolder {

            public static final Singleton INSTANCE = new Singleton();

        }
    }

但如果你不這樣做,為什么還要使用這樣的工廠方法,因為你沒有通過它添加任何值(方法名稱語義,對象池,同步等)

線程安全是關於訪問不同線程之間的共享數據。 示例中的代碼本身不訪問共享數據,但它是否是線程安全的取決於構造函數是否訪問可以在不同線程之間共享的數據。

關於並發編程,有許多微妙和難以處理的問題。 如果您想了解Java中的線程安全性和並發編程,那么我強烈推薦Brian Goetz撰寫的Java Concurrency in Practice一書。

多個線程可以調用此方法,每個線程都將獲得一個“實體”的唯一實例。 所以這個方法“本身”是線程安全的。 但是如果構造函數或其中一個非線程安全的超級構造函數中存在代碼,則無論如何都可能存在安全問題。

暫無
暫無

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

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