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

溫馨提示×

溫馨提示×

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

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

java多線程的核心知識點是什么

發布時間:2021-07-15 09:20:32 來源:億速云 閱讀:162 作者:chen 欄目:開發技術

這篇文章主要介紹“java多線程的核心知識點是什么”,在日常操作中,相信很多人在java多線程的核心知識點是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java多線程的核心知識點是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 一、鎖的概念

  • 二、synchronized 的使用方式

  • 三、synchronized 的實現原理列

    • 小結

  • 四、線程池是什么

    • 五、為什么要用線程池?

      • 六、看下類圖,從整體上理解下

        • 七、線程池的創建

          • 八、線程池核心參數說明

            • 九、幾個疑問點

              • 9.1、是怎么保證線程不銷毀的?

              • 9.2 提交任務有哪幾種方式?

              • 9.3 拒絕策略都有哪些?

              • 9.4 線程池的關閉

              • 9.5 初始化線程池時線程數的選擇

            • 十、總結

              一、鎖的概念

              先來聊聊這幾個概念,總不能聊起來的時候啥也不知道,只知道干活也沒有用。

              公平鎖:當線程A獲取訪問該對象,獲取到鎖后,此時內部存在一個計數器num+1,其他線程想訪問該對象,就會進行排隊等待(等待隊列最前一個線程處于待喚醒狀態),直到線程A釋放鎖(num = 0),此時會喚醒處于待喚醒狀態的線程進行獲取鎖的操作,一直循環。如果線程A再次嘗試獲取該對象鎖時,會檢查該對象鎖釋放已經被占用,如果還是當前線程占用鎖,則直接獲得鎖,不用進入排隊。

              非公平鎖:當線程A在釋放鎖后,等待對象的線程會進行資源競爭,競爭成功的線程將獲取該鎖,其他線程繼續睡眠。

              公平鎖是嚴格的以FIFO的方式進行鎖的競爭,但是非公平鎖是無序的鎖競爭,剛釋放鎖的線程很大程度上能比較快的獲取到鎖,隊列中的線程只能等待,所以非公平鎖可能會有“饑餓”的問題。但是重復的鎖獲取能減小線程之間的切換,而公平鎖則是嚴格的線程切換,這樣對操作系統的影響是比較大的,所以非公平鎖的吞吐量是大于公平鎖的,這也是為什么JDK將非公平鎖作為默認的實現。

              悲觀鎖:總是假設最壞的情況,每次想要使用數據的時候就恰好別人也要修改數據,一切是以安全第一,所以在每次操作資源的時候都會先加鎖,不管有沒有人搶,然后獨占資源。Java中synchronized和ReentrantLock等獨占鎖就是悲觀鎖思想的實現

              樂觀鎖:樂觀鎖和悲觀鎖剛好相反,假定自己使用資源的時候沒有人搶,所以不需要上鎖。樂觀鎖的實現方案一般來說有兩種:版本號機制 和 CAS實現 。下期可能會講。

              在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現方式CAS實現的。

              二、synchronized 的使用方式

              場景具體分類鎖對象代碼示例
              修飾方法實例方法當前實例對象public synchronized void method () { ... }
              ...靜態方法當前類的Class對象public static synchronized void method () { ... }
              修飾代碼塊代碼塊( )中配置的對象synchronized(object) { ... }

              三、synchronized 的實現原理列

              想知道原來先去底層看下,看看字節碼是什么樣子的,let's go!

                private static Object lock = new Object();
                public static synchronized void testSyn() {
                    System.out.println("香菜");
                }
                public synchronized void testSyn2() {
                    System.out.println("香菜");
                }
                public static void testObj() {
                    synchronized (lock) {
                        System.out.println("香菜");
                    }
                }

              看下字節碼:

              java多線程的核心知識點是什么

              可以看到synchronized 的地方使用的是monitorenter指令,每個對象都和一個monitor對象關聯,主要用來控制互斥資源的訪問,如果你想要加鎖必須先獲得monitor的批準,如果現在正有線程訪問,會把申請的線程加入到等待隊列。

              小結

              1、 無論synchronized關鍵字加在方法上還是對象上,如果它作用的對象是非靜態的,則它取得的鎖是對象;如果synchronized作用的對象是一個靜態方法或一個類,則它取得的鎖是對class對象的鎖,該類所有的對象同一把鎖。2、每個對象只有一個鎖(lock)與之相關聯,誰拿到這個鎖誰就可以運行它所控制的那段代碼。

              3、實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制,避免做嵌套synchronized 的使用。

              4、synchronized 要盡量控制范圍,不能范圍太大,否則會損失系統性能。

              四、線程池是什么

              線程池就是一個對象持有一堆線程,舉個例子就是餓了么養的騎手團隊。線程池就是這個團隊,每個騎手都是一個線程。

              五、為什么要用線程池?

              假如現在商家有外賣單子,需要騎手去送單,這個時候的外賣任務就會派單給騎手,為什么要用線程池吶?

              有幾個好處,第一就是騎手的招聘是有成本的,等你有了外賣訂單再去招聘,來不及了,不如平常養一些騎手,線程的創建和銷毀的開銷是巨大的。

              第二就是不能一個單子來了就來一個騎手,這樣的話騎手的數量很難控制,對于派單來說也存在很大的壓力,會造成整個騎手團隊的崩潰,對應的就是可以通過線程池控制系統內的線程數量,有效的避免大量的線程池爭奪CPU資源而造成堵塞。

              第三如果養了一個騎手團隊,這樣在騎手的管理上可以規范,以便提供更好的外賣服務,比如這種外賣超時,騎手打星等。對比線程池就是線程池可以提供定時、定期、單線程、并發數控制等功能。

              六、看下類圖,從整體上理解下

              java多線程的核心知識點是什么

              七、線程池的創建

              java多線程的核心知識點是什么

              線程池主要使用的四種

              固定數量的線程池(FixedThreadPool

              定時線程池(ScheduledThreadPool

              可緩存線程池(CachedThreadPool

              單線程化線程池(SingleThreadExecutor

              八、線程池核心參數說明

              首先看下如何構造一個線程池

                public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
                    return new ThreadPoolExecutor(nThreads, nThreads,
                                                  0L, TimeUnit.MILLISECONDS,
                                                  new LinkedBlockingQueue<Runnable>(),
                                                  threadFactory);
                    public ThreadPoolExecutor(int corePoolSize,
                                          int maximumPoolSize,
                                          long keepAliveTime,
                                          TimeUnit unit,
                                          BlockingQueue<Runnable> workQueue,
                                          ThreadFactory threadFactory,
                                          RejectedExecutionHandler handler)

              核心參數說明:

              java多線程的核心知識點是什么

              九、幾個疑問點

              9.1、是怎么保證線程不銷毀的?

              核心線程會阻塞等待workQueue

              9.2 提交任務有哪幾種方式?

              java多線程的核心知識點是什么

              9.3 拒絕策略都有哪些?

              拒絕策略(handler)當線程池的線程數達到最大線程數時,需要執行拒絕策略。拒絕策略需要實現RejectedExecutionHandler接口,并實現rejectedExecution(Runnable r, ThreadPoolExecutor executor)方法。不過Executors框架已經為我們實現了4種拒絕策略:

              AbortPolicy(默認):丟棄任務并拋出RejectedExecutionException異常。

              CallerRunsPolicy:由調用線程處理該任務。

              DiscardPolicy:丟棄任務,但是不拋出異常。可以配合這種模式進行自定義的處理方式。

              DiscardOldestPolicy:丟棄隊列最早的未處理任務,然后重新嘗試執行任務。

              9.4 線程池的關閉

              關閉線程池可以調用shutdownNow和shutdown兩個方法來實現

              shutdownNow:對正在執行的任務全部發出interrupt(),停止執行,對還未開始執行的任務全部取消,并且返回還沒開始的任務列表。

              shutdown:當我們調用shutdown后,線程池將不再接受新的任務,但也不會去強制終止已經提交或者正在執行中的任務。

              9.5 初始化線程池時線程數的選擇

              如果任務是IO密集型,一般線程數需要設置2倍CPU數以上,以此來盡量利用CPU資源。

              如果任務是CPU密集型,一般線程數量只需要設置CPU數加1即可,更多的線程數也只能增加上下文切換,不能增加CPU利用率。

              具體問題具體分析。

              十、總結

              線程池是項目中常用的,需要理解線程池的應用場景和構造函數,正確的使用線程池。

              到此,關于“java多線程的核心知識點是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

              向AI問一下細節

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

              AI

              和平县| 蒲江县| 三穗县| 华坪县| 澎湖县| 夏津县| 平安县| 南澳县| 台南市| 平阴县| 麻江县| 岗巴县| 富源县| 十堰市| 景东| 台前县| 乐山市| 泾阳县| 游戏| 讷河市| 密山市| 洪泽县| 榆社县| 宁河县| 宁蒗| 浪卡子县| 日喀则市| 柳州市| 民县| 连城县| 宽城| 郑州市| 大余县| 讷河市| 双流县| 洪泽县| 正宁县| 磐安县| 公安县| 五家渠市| 老河口市|