91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java基礎學習之-多線程學習知識點的學習

發布時間:2020-06-28 16:37:09 來源:網絡 閱讀:775 作者:sbp810050504 欄目:編程語言

Java語言從設計之初就把多線程作為語言的核心, 至少從以下幾點可以看出:

1. Object對象的wait和notify機制。
2. Thread類在lang包中。
3. synchronized volatile關鍵字。

雖然多線程是Java語言本身的特性,但是線程并不是Java語言獨有的東西,而是操作系統的特性。Java在語言層面進行了封裝,使其使用更簡單。

多線程存在的價值在哪里呢? 內存讀寫,磁盤IO, 網絡傳輸的速率遠遠低于CPU處理數據的速度。所以在大部分場景下,CPU是閑置的。有了多線程,就可以更多地壓榨CPU。所以,多線程在Web服務器,Lucene這類IO密集型的應用中大行其道。

多線程,知識點龐雜,但常用的核心知識點只有兩個: 資源同步 和 線程池。

學習多線程,私以為這樣的先后順序比較好。

step1: 學習多線程的創建和運行, Thread類和Runnable接口, 通常自定義類是實現Runnable接口,并非Thread類。

public class ThreadDemo {

    static class Worker impelements Runnable{

        private String name;

        public Worker(String name){
            this.name = name;
        }

        public void run(){
            System.out.println(this.name+": "+Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        Thread a1 = new Thread(new Worker("nameA"));
        Thread a2 = new Thread(new Worker("nameB"));
        a1.start();
        a2.start();
    }
}

step2: 學習synchronized/volatile關鍵字

由于內存讀寫遠比CPU執行的速度慢,出于提升性能的考慮,計算機設計者在CPU和內存之間架設了緩存,就是通常我們看到的L1, L2, L3。1個CPU周期需要0.3ns,L1緩存只需要0.9ns, 內存訪問需要120ns。 差距達百倍, 可見緩存對性能的提升。如果我們在一個線程里讀寫一個變量,將初始值加到緩存后, CPU只需和緩存之間交互就可以了。

由于線程之間并不共享緩存,所以多個線程讀寫同一個變量時,就有可能出現不一致的情況。多個線程出現了信息的不對稱, 如何解決這個問題呢? 就像銀行辦理業務一樣,每個人辦理業務前先取個號。這個號就類似Java里面的鎖機制。 synchronized就是Java的內置鎖。 volatile可以看作synchronized的簡化版, 因為它只能適用于某些特定的場景:

1. 修改變量不依賴其當前的值
2. 變量不跟其他變量一起對外作為整體

關于volatile的學習,個人覺得IBM的Java theory and practice Managing volatility是極好的學習資料。

step3: 學習ReentrantLock。了解了鎖的使用場景后,可以先學習JUC實現的鎖,最簡單的就是ReentrantLock。ReentrantLock是互斥鎖,可作為synchronized的代替品。

import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo {

    static class Counter implements Runnable{

        private int count;

        private ReentrantLock lock = new ReentrantLock();

        public void run(){
            try{
                lock.lock();
                count +=1;
            }finally {
                lock.unlock();
            }
        }

        public int getCount() {
            return count;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Counter a1 = new Counter();
        for(int i=0;i<1000;i++){
            new Thread(a1).start();
        }
        Thread.sleep(1000);
        System.out.println(a1.getCount());
    }
}

使用了ReentrantLock后,最好是能理解鎖的實現原理,即大名頂頂的AQS。但是學習AQS之前,需要一些預備知識。

1. volatile關鍵字的使用場景及限制
2. Unsafe.compareAndSwap的使用
3. Unsafe.park/unpark的使用
4. 數據結構鏈表的原理

整個JUC的鎖,線程安全的隊列都是基于AQS構建的。

step4: 學習AQS的原理。AQS基于鏈表構建的隊列來存儲爭用鎖的線程。當線程沒有獲取到鎖,就會使用Unsafe.park將線程掛起;其他的線程釋放鎖時,就會調用Unsafe.unpark將掛起的線程恢復。

step5: 了解了AQS的原理后,再學習ReentrantReadWriteLock, Semaphore, Phase, CountDownLatch, CyclicBarrier 這些同步工具,就沒那么難理解了。

step6: 學習BlockingQueue及其子類。 各種阻塞隊列,使用頻度比較高的是ArrayBlockingQueue, LinkedBlockingQueue.

step7: 學習線程池,主要是ThreadPoolExecutor類, ThreadPoolExecutor的核心是Worker類,每個Worker對應著一個線程。需要注意的是使用ThreadPoolExecutor時,阻塞隊列一定要要指定大小。不然線程池的RejectPolicy就不起作用了。 具體的細節需要更深入的分析。

關于多線程的知識點, 一篇筆記是遠遠不夠的,本文僅僅梳理學習的脈絡。

參考文檔:

https://www.ibm.com/developerworks/library/j-jtp06197/index.html

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万全县| 兴安盟| 泊头市| 探索| 宁波市| 枞阳县| 伊宁市| 得荣县| 天台县| 博湖县| 田林县| 宁波市| 民勤县| 曲沃县| 晋江市| 晴隆县| 金坛市| 微山县| 江永县| 隆昌县| 丰都县| 米泉市| 泾川县| 栖霞市| 九江市| 博罗县| 长沙县| 连江县| 锡林郭勒盟| 商都县| 尉犁县| 龙门县| 磐安县| 托克逊县| 中宁县| 河池市| 闻喜县| 南充市| 宿州市| 仁布县| 油尖旺区|