多核CPU的多個核可以同時訪問內存嗎?

目前的x86/x64的多核/多處理器系統是SMP結構,共享主存,內存是共享設備,多個處理器/核心要訪問內存,首先要獲得內存總線的控制權,任何時刻只有一個處理器/核心能獲得內存總線的控制權,所以單就內存來說,不會出現多個處理器/核心同時訪問一個內存地址的情況。但是每個處理器/核心可能有自己的cache(非共享的),所以,如果某個內存地址的數據在多個處理器/核心的cache中都存在的話,是可能出現併發讀的情況,對於讀寫,或者寫寫的併發操作,處理器實現的cache一致性協議可以保證物理上不會出現真正的併發操作。

所以對於你在多線程中訪問的整數,理論上是可以不加鎖訪問的,但是你必須保證訪問它的操作是原子的,這就與你的使用方式和編譯器生成的代碼有關。
簡單賦值是沒有問題的,比如i = 1; 但是涉及到其他變量的複合賦值就不能保證了,比如i = j; i = j + 1;
自增/自減操作,象i++、i–、i = i + 1;i = i - 1;等等,與編譯器生成的代碼有關,如果使用inc/dec指令,是沒有問題的,如果使用mov、add/sub、mov指令序列,則不能保證操作的原子性。
比較操作,除非顯式使用cmpxchg指令,否則不能保證操作的原子性。

所以,如果你的多線程共享數據是隻讀的,或者多讀一寫模型,那麼你可以不用加鎖訪問,否則你最好還是要加鎖。

Java多線程
之前對於Java synchronize重量級鎖的理解一直是操作系統的互斥鎖,也就是通過開關中斷來保證的線程對臨界區代碼的獨佔訪問。如果是單核的話,並沒有什麼問題。

但我今天想到,Java的多線程應該是可以利用多核的,在並行的情況下,如果CPU1上運行線程1,CPU2上運行線程2,僅僅在單CPU上開關中斷是無法保證線程安全的,那麼它又是怎麼實現的呢,通過CAS?

併發並不需要多核處理器,一般說的併發都是指單核上的多線程。那我們通常討論的Java併發編程,難道其實只涉及單CPU?我感覺應該不是吧。。如果Java的多線程確實利用了多核並行,我們爲什麼又不說並行編程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章