java-實戰java高併發程序設計-ch2java並行程序基礎

java並行程序基礎

參考:
https://github.com/chengbingh...java

2.1 有關線程, 須要知道的事

進程是線程的容器
線程狀態圖:git

clipboard.png
2.2 線程的基本操做
2.2.1新建線程
2.2.2終止線程
stop 暴力終止線程,廢棄方法github

clipboard.png
clipboard.png

2.2.3線程中斷
方法:
clipboard.png多線程

clipboard.png

2.2.4 等待(wait)和喚醒notify
注意:
wait 是object的一個方法,調用wait方法的對象,必須在synchronized 中,由於要獲取它的監視器。
wait會釋放鎖併發

public class SimpleWN {

    final static Object obj = new Object();
    
    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(obj) {
                    System.out.println("t1.start,and t1 will wait");
                    try {
                        // 調用wait 方法的這個對象必須被synchronizeed
                        //wait 會釋放鎖
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1 was notify");


                }

            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(obj){
                    System.out.println("t2 start and will notify t1");
                    // 調用notify 方法的這個對象必須被synchronizeed
                    //若是 有n個線程此時都是因爲調用了obj.wait方法,那麼會喚醒任意一個
                    obj.notify();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("t2 end run");
                }
            }
        });
        t1.start();
        t2.start();
    }
}
輸出:注意鎖
t1.start,and t1 will wait
t2 start and will notify t1
t2 end run
t1 was notify

2.2.5 掛起(suspend)和繼續執行(resume)
suspend()和resume方法ide

clipboard.png

clipboard.png

2.2.6 join 和yeild
join:加入,把線程當作一個方法了。
yeild:讓出線程執行權,可是仍是會爭奪線程的執行權
clipboard.png優化

2.3 volatile 與java 內存模型(JMM)

JMM: 原子性,可見性,有序性
原子性:32位虛擬機中多線程讀寫long不會有問題,可是不能保證i++spa

可見性:
虛擬機在-server模式下會進行優化,下面的程序永遠不會跳出。線程

/**
 * @author ChengBing Han
 * @date 9:39  2018/6/22
 * @description
 */
public class NoVisibility {
    private static boolean ready;
    private static int number;


    private static class ReaderThread extends Thread {
        public void run() {

            /*
           while (!ready){
                System.out.println(new Date());
            }*/
            //這個和上述的優化不一樣,這個在-server模式下會優化
            while (!ready) ;
            System.out.println(number);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        
        //永遠不會終止程序
        new ReaderThread().start();
        Thread.sleep(1000);
        number = 42;
        ready = true;
        Thread.sleep(2000);
    }
}

備註:上述ready 用volatile 修飾後就會退出,或者用-client 模式啓動虛擬機code

clipboard.png

clipboard.png

2.4 分門別類的管理 線程組

2.5 駐守線程的後臺:守護線程

2.6 線程優先級:先乾重要的事

1-10,優先級逐漸升高

2.7 synchronized(內部鎖)
volatile 能夠保證原子性,和可見性,可是若是兩個線程同時修改了某個變量,那麼仍是沒法識別的,這時volatile的侷限性。因此須要synchronized等來確保


clipboard.png

2.8 程序中隱蔽的錯誤

2.8.1 沒有提示的錯誤e
好比兩個正數int 相加, 溢出致使 其值爲負數。

2.8.2 併發下的ArrayList
兩個線程同時對一個ArrayList add 對象,每一個線程add 10000 個對象, 最終結果
可能1:ArrayList 中有2萬個對象。
可能2:拋出異常
ArrayList 內部結構被破壞了
clipboard.png
clipboard.png

可能3:ArrayList 中的對象個數小於2萬

clipboard.png

2.8.3 併發下的HashMap
兩個線程同時對HashMap添加對象,每一個線程add 10000 個對象,最終結果
可能1:HashMap 中有2萬個對象。
可能2:對象個數少於2萬
可能3:HashMap內部結構發生破壞,程序沒法終止,cpu會被大量消耗。
2.8.4 錯誤加鎖

static Integer i = 0;
.........
synchronized(i){
   i++;
}
//問題在於, integer是不可變的,因此每次i++都會建立一個新的對象。能夠用javap 反編譯查看

容許多個線程同時訪問:信號量

容許幾個線程訪問

clipboard.png

clipboard.png

clipboard.png

相關文章
相關標籤/搜索