亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Java并發(fā)編程中的線程

 更新時間:2023年08月11日 08:45:23   作者:劉婉晴  
這篇文章主要介紹了淺談Java并發(fā)編程中的線程,操作系統(tǒng)運行一個程序,就會創(chuàng)建一個進程,在一個進程里可以創(chuàng)建多個線程,因此線程也叫做輕量級進程,需要的朋友可以參考下

一、線程

線程是操作系統(tǒng)調度的最小單元,多線程同時執(zhí)行,可以提高程序性能 。

1. 什么是線程

操作系統(tǒng)運行一個程序,就會創(chuàng)建一個進程,在一個進程里可以創(chuàng)建多個線程,因此線程也叫做輕量級進程 。

2. 線程帶來了什么好處

現代處理器都是多核的,程序運行過程中能夠創(chuàng)建多個線程,而一個線程在一個時刻只能運行在一個處理器核心上,如果一個單線程程序在運行時只能使用一個處理器核心,那么再多的處理器核心加入也無法顯著提升該程序的執(zhí)行效率。

3. 線程基礎

(1)優(yōu)先級 —— setPriority(int)

線程優(yōu)先級決定線程需要多或者少分配一些處理器資源的線程屬性

設置線程優(yōu)先級時,針對頻繁阻塞(休眠或者I/O操作)的線程需要設置較高優(yōu)先級,而偏重計算(需要較多CPU時間或者偏運算)的線程則設置較低的優(yōu)先級,確保處理器不會被獨占。

程序正確性不能依賴于優(yōu)先級高低 —— 不同操作系統(tǒng)有不同的處理方式

(2)狀態(tài)

New 初始態(tài)\ Running 運行態(tài) \ Blocked 阻塞態(tài) \Waiting 等待態(tài)\ TimeWaiting 超時等待態(tài)\ Terminated 終止態(tài)

注: Java將操作系統(tǒng)中的運行和就緒兩個狀態(tài)合并稱為運行狀態(tài)

阻塞狀態(tài)是線程阻塞在進入synchronized關鍵字修飾的方法或代碼塊(獲取鎖)時的狀態(tài),但是阻塞在java.concurrent包中Lock接口的線程狀態(tài)卻是等待狀態(tài),因為java.concurrent包中Lock接口對于阻塞的實現均使用了LockSupport類中的相關方法。

(3)Daemon 線程 —— setDaemon(true)

支持型線程,用作程序中臺調度以及支持性工作 當一個Java虛擬機中不存在非Daemon線程的時候,Java虛擬機將會退出

(4)線程的啟動和終止

新構造的線程對象是由其parent線程來進行空間分配的,child線程繼承了parent是否為Daemon、優(yōu)先級和加載資源的contextClassLoader以及可繼承的ThreadLocal,同時還會分配一個唯一的ID來標識這個child線程,至此,一個能夠運行的線程對象就初始化好了。

start()方法的含義是:當前線程(即parent線程)同步告知Java虛擬機,只要線程規(guī)劃器空閑,應立即啟動調用start()方法的線程

(5)中斷

Thread.currentThread().isInterrupted()

  • 中斷可以理解為線程的一個標識位屬性,它表示一個運行中的線程是否被其他線程進行了中斷操作;
  • 中斷狀態(tài)是線程的一個標識位,中斷操作是一種簡便的線程間交互方式,這種交互方式適合用來取消或停止任務
  • 除了中斷以外,還可以利用一個boolean變量來控制是否需要停止任務并終止該線程

4. volatile和synchronized關鍵字

volatile

告知程序任何對該變量的訪問均需要從共享內存中獲取,而對它的改變必須同步刷新回共享內存,它能保證所有線程對變量訪問的可見性。

synchronized

關鍵字synchronized可以修飾方法或者以同步塊的形式來進行使用,它主要確保多個線程在同一個時刻,只能有一個線程處于方法或者同步塊中,它保證了線程對變量訪問的可見性和排他性。

本質是對一個對象的監(jiān)視器(monitor)進行獲取,而這個獲取過程是排他的,也就是同一時刻只能有一個線程獲取到由synchronized所保護對象的監(jiān)視器

任意一個對象都擁有自己的監(jiān)視器,當這個對象由同步塊或者這個對象的同步方法調用時,執(zhí)行方法的線程必須先獲取到該對象的監(jiān)視器才能進入同步塊或者同步方法,而沒有獲取到監(jiān)視器(執(zhí)行該方法)的線程將會被阻塞在同步塊和同步方法的入口處,進入BLOCKED狀態(tài)。

5. 等待通知

等待/通知機制是指一個線程A調用了對象O的wait()方法進入等待狀態(tài),而另一個線程B調用了對象O的notify()或者notifyAll()方法,線程A收到通知后從對象O的wait()方法返回,進而執(zhí)行后續(xù)操作。

等待/通知的相關方法是任意Java對象都具備的,因為這些方法被定義在所有對象的超類java.lang.Object上。

  • 使用wait()、notify()和notifyAll()時需要先對調用對象加鎖;
  • 調用wait()方法后,線程狀態(tài)由RUNNING變?yōu)閃AITING,并將當前線程放置到對象的等待隊列;
  • notify()或notifyAll()方法調用后,等待線程依舊不會從wait()返回,需要調用notify()或notifAll()的線程釋放鎖之后,等待線程才有機會從wait()返回;
  • notify()方法將等待隊列中的一個等待線程從等待隊列中移到同步隊列中,而notifyAll()方法則是將等待隊列中所有的線程全部移到同步隊列,被移動的線程狀態(tài)由WAITING變?yōu)锽LOCKED;
  • 從wait()方法返回的前提是獲得了調用對象的鎖。
synchronized(對象) {
       while(條件不滿足) {
            對象.wait();
       }
       對應的處理邏輯
}
synchronized(對象) {
       改變條件
       對象.notifyAll();
}

(1)Thread.join()

線程A執(zhí)行了thread.join()語句,其含義是:當前線程A等待thread線程終止之后才從thread.join()返回

join() 當線程終止時,會調用線程自身的notifyAll()方法,會通知所有等待在該線程對象上的線程。

(2)ThreadLocal

以ThreadLocal對象為鍵、任意對象為值的存儲結構,一個線程可以根據一個ThreadLocal對象查詢到綁定在這個線程上的一個值。

ThreadLocal 調用耗時統(tǒng)計的功能上,在方法的入口前執(zhí)行begin()方法,在方法調用后執(zhí)行end()方法,好處是兩個方法的調用不用在一個方法或者類中,比如在AOP(面向方面編程)中,可以在方法調用前的切入點執(zhí)行begin()方法,而在方法調用后的切入點執(zhí)行end()方法,這樣依舊可以獲得方法的執(zhí)行耗時。

6. 如何實現等待超時模式

場景:調用一個方法時等待一段時間0,如果該方法能夠在給定的時間段之內得到結果,那么將結果立刻返回,反之,超時返回默認結果 。

解決:對象加鎖 條件循環(huán) 處理邏輯 + 設置超時時間段

應用:超時等待模式可以用來實現 數據庫連接池 中數據庫連接操作超時返回

好處: 保證客戶端線程不會一直掛在連接獲取的操作上,而是“按時”返回,并告知客戶端連接獲取出現問題,是系統(tǒng)的一種自我保護機制,針對昂貴資源(比如數據庫連接)的獲取都應該加以超時限制。

7. 線程池

為什么需要考慮 C/S 架構的程序,如果沒有線程池, 我們客戶端向服務器發(fā)的請求,每個請求創(chuàng)建一個線程,假設我們有 1 萬個請求, 那么就需要創(chuàng)建 1 萬的線程進行處理。 眾所周知,線程的創(chuàng)建和上下文切換是非常消耗資源的。因此, 需要線程池技術解決這個問題 。

線程池好處

  • 消除了頻繁創(chuàng)建和消亡線程的系統(tǒng)資源開銷
  • 面對過量任務的提交能夠平緩的劣化

線程池的默認實現

使用一個線程安全的工作隊列連接工作者線程和客戶端線程。

線程池種類

newSingleThreadExecutor newFixedThreadPool newCachedThreadPool : 提高執(zhí)行許多短暫的異步任務的程序的性能

線程池應用:

簡單的 Web 服務器 常用的Java Web服務器,如Tomcat、Jetty,在其處理請求的過程中都使用到了線程池技術。

因為我們不能一個一個請求的順序處理,這樣的話,估計就沒有用戶會想用了 ?,F代的瀏覽器可以并發(fā)發(fā)送多個請求, 服務器可以并發(fā)處理多個請求 。

線程池中線程數量設置

線程池中線程數量并不是越多越好,具體的數量需要評估每個任務的處理時間,以及當前計算機的處理器能力和數量。使用的線程過少,無法發(fā)揮處理器的性能;使用的線程過多,將會增加系統(tǒng)的無故開銷,起到相反的作用。

((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數目

線程池可能出現的問題

  • 使用默認的無界的阻塞隊列,任務過多,導致阻塞隊列炸了 OOM 使用newFixedThreadPool創(chuàng)建的線程池默認的是無界的阻塞隊列,如果任務過多,會導致OOM問題。因此,建議自定義線程池,使用指定長度的阻塞隊列
  • 線程池創(chuàng)建線程過多,導致JVM無法創(chuàng)建出更多線程,從而導致OOM 使用newCachedThreadPool創(chuàng)建的線程池時,其對線程數量沒有規(guī)定,如果某個業(yè)務的請求特別多,也會導致OOM (因為 newCachedThreadPool 創(chuàng)建的線程沒有規(guī)定數量,完全由 JVM 能創(chuàng)建的線程數量而定)
  • 不同業(yè)務共享線程池,導致次要邏輯拖主要邏輯
  • 線程池拒絕策略 使用不合理的拒絕策略,可能會導致阻塞問題 。比如使用 DiscardPolicy 或者 DiscardOldestPolicy 策略 并且 被拒絕的任務調用 get() 方法,那么調用線程就會一直被阻塞 (FutureTask的狀態(tài)大于COMPLETING才會返回,要不然都會一直阻塞等待。),這也和 get() 方法本身的問題有關,其不帶超時時間,可能會導致阻塞 。
  • Spring 內置線程池 (使用內置線程池一定要注意其時如何創(chuàng)建銷毀線程的)
  • 自定義命名
  • 線程池參數 —— 最佳線程數量,每個都要好好配置,做到心中有數
  • 異常問題 (submit 不會直接拋出異常, execute 可以 ,最好是try…catch捕獲 )
  • 忘記關閉

到此這篇關于淺談Java并發(fā)編程中的線程的文章就介紹到這了,更多相關Java中的線程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Ubuntu 安裝 JDK8 的兩種方法(總結)

    Ubuntu 安裝 JDK8 的兩種方法(總結)

    下面小編就為大家?guī)硪黄猆buntu 安裝 JDK8 的兩種方法(總結)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • SpringBoot多種自定義錯誤頁面方式小結

    SpringBoot多種自定義錯誤頁面方式小結

    這篇文章主要介紹了SpringBoot多種自定義錯誤頁面方式小結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 深入淺出解析Java ThreadLocal原理

    深入淺出解析Java ThreadLocal原理

    ThreadLocal是JDK包提供的,它提供線程本地變量,如果創(chuàng)建一樂ThreadLocal變量,那么訪問這個變量的每個線程都會有這個變量的一個副本,在實際多線程操作的時候,操作的是自己本地內存中的變量,從而規(guī)避了線程安全問題,感興趣的朋友快來看看吧
    2021-11-11
  • spring boot 命令行啟動的方式

    spring boot 命令行啟動的方式

    這篇文章主要介紹了spring boot 命令行啟動的方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Spring框架的環(huán)境搭建和測試實現

    Spring框架的環(huán)境搭建和測試實現

    這篇文章主要介紹了Spring框架的環(huán)境搭建和測試實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • Java使用mapstruct實現對象拷貝

    Java使用mapstruct實現對象拷貝

    MapStruct可以簡化對象之間的映射,本文就來介紹一下Java使用mapstruct實現對象拷貝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Mybatis?在?insert?插入操作后返回主鍵?id的操作方法

    Mybatis?在?insert?插入操作后返回主鍵?id的操作方法

    這篇文章主要介紹了Mybatis?在?insert?插入操作后返回主鍵?id的操作方法,本文結合示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • 詳解Java如何實現自定義注解

    詳解Java如何實現自定義注解

    注解(Annotation),也叫元數據。一種代碼級別的說明。它是JDK1.5及以后版本引入的一個特性,與類、接口、枚舉是在同一個層次。本文將通過示例詳解Java如何實現自定義注解,需要的可以參考一下
    2022-06-06
  • 解決SpringBoot中LocalDateTime返回前端數據為數組結構的問題

    解決SpringBoot中LocalDateTime返回前端數據為數組結構的問題

    本文主要介紹了解決SpringBoot中LocalDateTime返回前端數據為數組結構的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-03-03
  • 解決java調用dll報Unable to load library錯誤的問題

    解決java調用dll報Unable to load library錯誤的問題

    這篇文章主要介紹了解決java調用dll報Unable to load library錯誤的問題。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評論