欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線程的同步優(yōu)化的6種方案

 更新時間:2021年05月26日 11:58:34   作者:卜大爺  
大家使用多線程無非是為了提高性能,在Java中,有多線程并發(fā)時,我們可以使用多線程同步的方式來解決內(nèi)存一致性的問題。本文就詳細的介紹了Java多線程同步優(yōu)化,感興趣的可以了解一下

概述

處理器上的寄存器的讀寫的速度比內(nèi)存快幾個數(shù)量級,為了解決這種速度矛盾,在它們之間加入了高速緩存。

加入高速緩存帶來了一個新的問題:緩存一致性。如果多個緩存共享同一塊主內(nèi)存區(qū)域,那么多個緩存的數(shù)據(jù)可能會不一致,需要一些協(xié)議來解決這個問題。

在Java內(nèi)存模型中,分為主內(nèi)存和線程工作內(nèi)存,線程使用共享數(shù)據(jù)時,先從主內(nèi)存中拷貝數(shù)據(jù)到工作內(nèi)存,使用完成之后再寫入主內(nèi)存中。

在Java中,有多線程并發(fā)時,我們可以使用多線程同步的方式來解決內(nèi)存一致性的問題。通常我們可以在程序中添加同步鎖來保障數(shù)據(jù)的安全訪問,但是也經(jīng)常會帶來一些同步性能問題,那么本章將針對常見的同步問題給出了一些優(yōu)化方案。

讀寫鎖

在多線程操作下,如果我們的某些數(shù)據(jù)經(jīng)常被讀取操作,但非常少的時機被寫入操作。這時,如果我們使用synchronized等同步方式,性能會非常低。

這種場景下,我們應該使用讀寫鎖來進行優(yōu)化。

讀寫鎖的特點:

  • 讀寫鎖維護一對鎖,讀鎖和寫鎖。
  • 可以共享讀,但只能一個寫。
  • 讀讀不互斥,讀寫互斥,寫寫互斥。

某些特定的場景,使用讀寫鎖會極大的提高多線程并發(fā)操作的效率。因為,讀寫鎖中,讀鎖不是排它鎖,所以可以并發(fā)執(zhí)行,可以非常顯著的提高讀取效率;只有在寫鎖時,是排它鎖,這時需要等待寫鎖的釋放。

ReetrantReadWriteLock

ReadWriteLock接口

Java并發(fā)包中ReadWriteLock是一個接口,抽象了讀寫鎖方法:

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

ReadWriteLock管理一組鎖,一個是只讀的鎖,一個是寫鎖。

ReetrantReadWriteLock類

Java并發(fā)庫中ReetrantReadWriteLock實現(xiàn)了ReadWriteLock接口并添加了可重入的特性。

1. ReetrantReadWriteLock獲取鎖順序有兩種模式:

  • 非公平模式(默認):非公平鎖主張競爭獲取,可能會延緩一個或多個讀或?qū)懢€程,但是會比公平鎖有更高的吞吐量。
  • 公平模式:當以公平模式初始化時,線程將會以隊列的順序獲取鎖。

2. 可重入

ReetrantReadWriteLock鎖是可重入的,當然一個線程獲取多少次鎖,就必須釋放多少次鎖。

  • 讀線程獲取讀鎖之后能夠再次獲取讀鎖。
  • 寫線程獲取寫鎖之后能再次獲取寫鎖,也可以獲取讀鎖。

3. 鎖降級

在讀寫鎖中,鎖降級:從寫鎖變成讀鎖;鎖升級:從讀鎖變成寫鎖。

  • ReentrantReadWriteLock是不支持鎖升級的,也就是當一個線程持有了讀鎖,當該線程再次使用寫鎖時,是不可以的。如果一個線程持有了讀鎖,則在獲取寫鎖之前,一定要先釋放讀鎖。
  • ReentrantReadWriteLock支持鎖降級的,也就是如果當前線程是寫鎖的持有者,并保持獲得寫鎖的狀態(tài),同時又獲取到讀鎖,然后釋放寫鎖的過程。按照獲取寫鎖、獲取讀鎖、再釋放寫鎖的順序,即寫鎖能夠降級為讀鎖。

讀寫鎖狀態(tài)的設計

讀寫鎖的狀態(tài)是用一個int值來表示的。state(int32位)字段分成高16位與低16位,其中高16位表示讀鎖個數(shù),低16位表示寫鎖個數(shù)。

例如,當前一個線程獲取到了寫鎖,并且重入了兩次,因此低16位是3,并且該線程又獲取了讀鎖,并且重入了一次,所以高16位是2,當寫鎖被獲取時如果讀鎖不為0那么讀鎖一定是獲取寫鎖的這個線程。

寫時復制

寫時復制(Copy-on-write,簡稱COW)是一種計算機程序設計領域的優(yōu)化策略。其核心思想是,如果有多個調(diào)用者同時要求相同資源,他們會共同獲取相同的指針指向相同的資源,直到某個調(diào)用者試圖修改資源的內(nèi)容時,系統(tǒng)才會真正復制一份專用副本給該調(diào)用者,而其他調(diào)用者所見到的最初的資源仍然保持不變。這過程對其他的調(diào)用者都是透明的。此作法主要的優(yōu)點是如果調(diào)用者沒有修改該資源,就不會有副本被創(chuàng)建,因此多個調(diào)用者只是讀取操作時可以共享同一份資源。

在Java中,Copy on Write這種機制通常用在集合上,在并發(fā)訪問的情景下,當需要修改JAVA中Containers的元素時,不直接修改該容器,而是先復制一份副本,在副本上進行修改。修改完成之后,將指向原來容器的引用指向新的容器(副本容器)。

寫時復制的特點

  • 由于不會修改原始容器,只修改副本容器。因此,可以對原始容器進行并發(fā)地讀。其次,實現(xiàn)了讀操作與寫操作的分離,讀操作發(fā)生在原始容器上,寫操作發(fā)生在副本容器上。
  • 數(shù)據(jù)一致性問題:因為修改操作發(fā)生在副本上,讀操作的線程可能不會立即讀取到新修改的數(shù)據(jù)內(nèi)容,但最終修改操作會完成并更新容器,因此這是最終一致性。
  • CopyOnWrite容器適用于讀多寫少的場景。寫操作時,需要復制一個容器,會造成很大的內(nèi)存開銷。
  • 不適合于數(shù)據(jù)的強一致性場合。若要求數(shù)據(jù)修改之后立即能被讀到,則不能用寫時復制技術。因為它是最終一致性。

Java寫時復制容器類

JDK中提供了CopyOnWriteArrayList類和CopyOnWriteArraySet類,實現(xiàn)了寫時復制。

減小鎖的粒度

如果我們在一個大的數(shù)據(jù)操作類里面,大量使用了鎖,并且還是同一個鎖,這時,我們的多線程同步效率就會變得非常低。

我們可以將數(shù)據(jù)按照不同的類型及應用場景進行分割,然后用不同的鎖進行同步,這樣,不同的場景下就不會產(chǎn)生排它鎖的沖突問題,可以大大提高同步的效率。

該方案簡單來說就是將一個大鎖,分割成多個小鎖,這樣就能顯著的提高多線程并發(fā)執(zhí)行的效率。

減小鎖的占有時間

如果在一個較大的方法中,我們直接給該方法加了一個鎖,但是我們需要同步的地方只是該方法中的一行操作代碼,這樣就是很糟糕的同步使用方式了。

我們可以將鎖細化到使用它的代碼行上,而不是整個函數(shù)都加鎖,這樣鎖的持有時間就會變少,從而提高了多線程同步的性能。

該方案是將同步塊的代碼范圍減小,從而降低鎖的持有時間,達到優(yōu)化多線程同步性能的目的。

鎖粗化

雖然說,減少鎖的占有時間可以提高性能,但是有時候,這種方式并不適用。

例如,一個循環(huán)中,我們在循環(huán)體中,使用了鎖,這樣反而會降低性能,這時我們應該在循環(huán)開始之前加鎖,結束之后釋放,也就是將鎖粗化。

這是為什么呢?

這是因為,頻繁的對鎖進行請求、釋放、狀態(tài)修改等操作,會造成大量系統(tǒng)資源的消耗,從而降低性能。

ThreadLocal

同步效率低,是因為多線程同步等待造成的,那么我們可以換一個思路,如果讓每個線程都持有一份數(shù)據(jù),那這樣就不會存在競爭的問題了,也就不需要同步鎖了。這樣就會很大程度上提高多線程并發(fā)的性能。

關于ThreadLocal相關實現(xiàn)原理及使用可以參考之前的文章《ThreadLocal線程本地對象原理分析》。

總結

Java中可以使用鎖來解決多線程的同步問題,保障了數(shù)據(jù)的一致性,但也會代理很多問題,本章總結了多線程同步的幾種優(yōu)化方案:

  • 某些特定的場景(大多是讀多、寫少的場景),使用讀寫鎖會極大的提高多線程并發(fā)操作的效率。因為,讀寫鎖中,讀鎖不是排它鎖,所以可以并發(fā)執(zhí)行,可以非常顯著的提高讀取效率;只有在寫鎖時,是排它鎖,這時需要等待寫鎖的釋放。
  • Java并發(fā)庫中ReetrantReadWriteLock實現(xiàn)了ReadWriteLock接口并添加了可重入的特性。
  • 寫時復制機制可以顯著提高并發(fā)效率,在并發(fā)訪問的情景下,當需要修改JAVA中Containers的元素時,不直接修改該容器,而是先復制一份副本,在副本上進行修改。修改完成之后,將指向原來容器的引用指向新的容器(副本容器)。CopyOnWrite容器適用于讀多寫少的場景。寫操作時,需要復制一個容器,會造成很大的內(nèi)存開銷。
  • 通過減小鎖的粒度,來提高同步效率。
  • 減小鎖的占有時間是指,通過將同步塊的代碼范圍減小,從而降低鎖的持有時間,達到優(yōu)化多線程同步性能的目的。
  • 有時,大量的鎖和鎖狀態(tài)修改會造成系統(tǒng)資源的消耗,我們可以通過鎖粗化來優(yōu)化性能。
  • 我們可以換一個思路,使用ThreadLocal來提高多線程并發(fā)的性能。

到此這篇關于Java多線程的同步優(yōu)化的6種方案的文章就介紹到這了,更多相關Java多線程同步優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java isPalindrome方法在密碼驗證中的應用

    java isPalindrome方法在密碼驗證中的應用

    這篇文章主要為大家介紹了java isPalindrome方法在密碼驗證中的簡單應用技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 如何使用IDEA從SVN服務端檢出項目

    如何使用IDEA從SVN服務端檢出項目

    這篇文章主要介紹了如何使用IDEA從SVN服務端檢出項目問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 聊聊Spring——AOP詳解(AOP概覽)

    聊聊Spring——AOP詳解(AOP概覽)

    這篇文章主要介紹了Spring——AOP詳解(AOP概覽),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java構造函數(shù)與普通函數(shù)用法詳解

    Java構造函數(shù)與普通函數(shù)用法詳解

    本篇文章給大家詳細講述了Java構造函數(shù)與普通函數(shù)用法以及相關知識點,對此有興趣的朋友可以參考學習下。
    2018-03-03
  • java實現(xiàn)簡單的猜數(shù)字小游戲

    java實現(xiàn)簡單的猜數(shù)字小游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單猜數(shù)字小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • SpringDataJPA實體類關系映射配置方式

    SpringDataJPA實體類關系映射配置方式

    這篇文章主要介紹了SpringDataJPA實體類關系映射配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot快速整合RabbitMq小案例(使用步驟)

    SpringBoot快速整合RabbitMq小案例(使用步驟)

    這篇文章主要介紹了SpringBoot快速整合RabbitMq小案例,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Spring定時任務@Scheduled注解(cron表達式fixedRate?fixedDelay)

    Spring定時任務@Scheduled注解(cron表達式fixedRate?fixedDelay)

    這篇文章主要為大家介紹了Spring定時任務@Scheduled注解(cron表達式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • java 多態(tài)性詳解及簡單實例

    java 多態(tài)性詳解及簡單實例

    這篇文章主要介紹了java 多態(tài)性詳解及簡單實例的相關資料,需要的朋友可以參考下
    2017-02-02
  • Java 整合模板徹底解決ssm配置難題

    Java 整合模板徹底解決ssm配置難題

    SSM框架是spring MVC ,spring和mybatis框架的整合,是標準的MVC模式,將整個系統(tǒng)劃分為表現(xiàn)層,controller層,service層,DAO層四層,使用spring MVC負責請求的轉(zhuǎn)發(fā)和視圖管理,spring實現(xiàn)業(yè)務對象管理,mybatis作為數(shù)據(jù)對象的持久化引擎
    2021-10-10

最新評論