java併發編程

一 併發三要素:

1 原子性

   synchronize,可修飾方法或塊

   ReentrantLock,同步鎖,例如 Lock lock = new ReentrantLock();   lock.lock(); lock.unlock();

2 可見性,也稱一致性

  2.1 volatile,禁止cpu指令重排序,java工作內存(本地線程所佔用空間)將共享變量的值立即寫到主存;

  2.2 volatile無法保證原則性


3 有序性

 滿足1和2,一般就滿足了有序性。

happens-before 八大原則----------深入理解jvm

  • 程序次序規則:一個線程內,按照代碼順序,書寫在前面的操作先行發生於書寫在後面的操作
  • 鎖定規則:一個unLock操作先行發生於後面對同一個鎖額lock操作
  • volatile變量規則:對一個變量的寫操作先行發生於後面對這個變量的讀操作
  • 傳遞規則:如果操作A先行發生於操作B,而操作B又先行發生於操作C,則可以得出操作A先行發生於操作C
  • 線程啓動規則:Thread對象的start()方法先行發生於此線程的每個一個動作
  • 線程中斷規則:對線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生
  • 線程終結規則:線程中所有的操作都先行發生於線程的終止檢測,我們可以通過Thread.join()方法結束、Thread.isAlive()的返回值手段檢測到線程已經終止執行
  • 對象終結規則:一個對象的初始化完成先行發生於他的finalize()方法的開始
4 實例

採用synchronized:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
publicclass Test {
    public int inc = 0;
 
    publicsynchronized void increase() {
        inc++;
    }
 
    publicstatic void main(String[] args) {
        finalTest test = newTest();
        for(inti=0;i<10;i++){
            newThread(){
                publicvoid run() {
                    for(intj=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
 
        while(Thread.activeCount()>1//保證前面的線程都執行完
            Thread.yield();
        System.out.println(test.inc);
    }
}

採用Lock:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
publicclass Test {
    public int inc = 0;
    Lock lock = newReentrantLock();
 
    public void increase() {
        lock.lock();
        try{
            inc++;
        }finally{
            lock.unlock();
        }
    }
 
    publicstatic void main(String[] args) {
        finalTest test = newTest();
        for(inti=0;i<10;i++){
            newThread(){
                publicvoid run() {
                    for(intj=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
 
        while(Thread.activeCount()>1//保證前面的線程都執行完
            Thread.yield();
        System.out.println(test.inc);
    }
}

採用AtomicInteger:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
publicclass Test {
    public AtomicInteger inc = newAtomicInteger();
 
    public void increase() {
        inc.getAndIncrement();
    }
 
    publicstatic void main(String[] args) {
        finalTest test = newTest();
        for(inti=0;i<10;i++){
            newThread(){
                publicvoid run() {
                    for(intj=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
 
        while(Thread.activeCount()>1//保證前面的線程都執行完
            Thread.yield();
        System.out.println(test.inc);
    }
}
在java 1.5的java.util.concurrent.atomic包下提供了一些原子操作類,即對基本數據類型的 自增(加1操作),自減(減1操作)、以及加法操作(加一個數),減法操作(減一個數)進行了封裝,保證這些操作是原子性操作。atomic是利用CAS來實現原子性操作的(Compare And Swap),CAS實際上是利用處理器提供的CMPXCHG指令實現的,而處理器執行CMPXCHG指令是一個原子性操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章