Java的多線程編程模型 1

發現對於Java的多線程編程模型需要深入瞭解,打算

Java多線程的類庫封裝在java.util.concurrent.*中,java1.4到1.5的變化就是引入了這個支持併發編程的類庫。首先得感謝下大名鼎鼎人類庫作者Doug Lea,牛人總是讓人膜拜的。

1 什麼是線程安全
A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.

譯成中文意思就是
多個線程訪問一個類時,如果不用考慮這些線程在運行時環境下的調度和交替運行,並且不需要額外的同步及在調用方代碼不必做其他的協調,這個類的行爲仍然是正確的,那麼這個類就是線程安全的。

從上面的解釋可以看出
無狀態對象永遠是線程安全的

2 什麼是原子性
多個線程執行一個操作時,其中任何一個線程要麼完全執行完此操作,要麼沒有執行此操作的任何步驟,那麼這個操作就是原子的

3 爲什麼線程不安全
看一個線程不安全的經典例子:
package zl.study.concurrency;

public class ReorderingDemo {
    static int x = 0, y = 0, a = 0, b = 0;

    public static void main(String[] args) throws Exception {

        for (int i = 0; i < 100; i++) {
            x=y=a=b=0;
            Thread one = new Thread() {
                public void run() {
                    a = 1;
                    x = b;
                }
            };
            Thread two = new Thread() {
                public void run() {
                    b = 1;
                    y = a;
                }
            };
            one.start();
            two.start();
            one.join();
            two.join();
            System.out.println(x + " " + y);
        }
    }

}
在這個例子中,如果你在一個單CPU的java測試環境中做測試,你可能只會得到一種結果(0,1),然而真的只有這樣一種情況麼?顯然不是。JVM並不能保證線程的執行順序,即使看起來你無數次測試都是(0,1),然而切換到別的環境中,出現其它結果(1,0)仍然是無法避免的。而在多CPU的結構中,就更不能保證了。線程可能在不同的CPU上執行,從而(0,0),(1,1)都是可能的。

4 爲什麼會出現這種情況
導致出現這些情況的原因有很多
Java內存分配
    寄存器:我們在程序中無法控制
    棧:存放基本類型的數據和對象的引用,但對象本身不存放在棧中,而是存放在堆中
    堆:存放用new產生的數據
    靜態域:存放在對象中用static定義的靜態成員   
    常量池:存放常量,比如.class信息,String

編譯器優化
    調整語句執行順序
    變量值存於寄存器而不是內存中
CPU自身的優化
    並行或者按其他順序執行
    CPU本身的Cache會延遲變量的值刷新到內存的時間

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