最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)中線程封閉知識點(diǎn)詳解

 更新時(shí)間:2019年07月16日 11:37:46   作者:鍋外的大佬  
在本篇文章里我們給大家整理了關(guān)于Java并發(fā)中線程封閉的知識點(diǎn)總結(jié)內(nèi)容,需要的朋友們學(xué)習(xí)參考下。

在這篇文章中,我們將探討線程封閉是什么意思,以及我們?nèi)绾螌?shí)現(xiàn)它。 所以,讓我們直接開始吧。

線程封閉基礎(chǔ)知識點(diǎn)

實(shí)現(xiàn)好的并發(fā)是一件困難的事情,所以很多時(shí)候我們都想躲避并發(fā)。避免并發(fā)最簡單的方法就是線程封閉。什么是線程封閉呢?

就是把對象封裝到一個線程里,只有這一個線程能看到此對象。那么這個對象就算不是線程安全的也不會出現(xiàn)任何安全問題。實(shí)現(xiàn)線程封閉有哪些方法呢?

1:ad-hoc線程封閉

這是完全靠實(shí)現(xiàn)者控制的線程封閉,他的線程封閉完全靠實(shí)現(xiàn)者實(shí)現(xiàn)。也是最糟糕的一種線程封閉。所以我們直接把他忽略掉吧。

2:棧封閉

棧封閉是我們編程當(dāng)中遇到的最多的線程封閉。什么是棧封閉呢?簡單的說就是局部變量。多個線程訪問一個方法,此方法中的
局部變量都會被拷貝一分兒到線程棧中。所以局部變量是不被多個線程所共享的,也就不會出現(xiàn)并發(fā)問題。所以能用局部變量就別用全局的變量,全局變量容易引起并發(fā)問題。

3:ThreadLocal封閉

使用ThreadLocal是實(shí)現(xiàn)線程封閉的最好方法,有興趣的朋友可以研究一下ThreadLocal的源碼,其實(shí)ThreadLocal內(nèi)部維護(hù)了一個Map,Map的key是每個線程的名稱,而Map的值就是我們要封閉的對象。每個線程中的對象都對應(yīng)著Map中一個值,也就是ThreadLocal利用Map實(shí)現(xiàn)了對象的線程封閉。這里就不說ThreadLocal的使用方法了,度娘一下便知。

1. 線程封閉

大多數(shù)的并發(fā)問題僅發(fā)生在我們想要在線程之間共享可變變量或可變狀態(tài)時(shí)。如果在多個線程之間操作共享變量,則所有線程都將能夠讀取和修改變量的值,從而出現(xiàn)意外或不正確的結(jié)果。一種簡單的避免此問題的方式是不在線程之間共享數(shù)據(jù)。 這種技術(shù)稱為線程封閉,是在我們的應(yīng)用程序中實(shí)現(xiàn)線程安全的最簡單方法之一。

Java 語言本身沒有任何強(qiáng)制執(zhí)行線程封閉的方法。線程封閉是通過不允許多個線程同時(shí)使用同一個狀態(tài)的方式的程序設(shè)計(jì)來實(shí)現(xiàn)的,因此由程序?qū)崿F(xiàn)強(qiáng)制執(zhí)行。 幾種類型的線程封閉,如下所示:

1.1 Ad-Hoc 線程封閉

Ad-hoc 線程封閉描述了線程封閉的方式,由開發(fā)人員或從事該項(xiàng)目的開發(fā)人員確保僅在單個線程內(nèi)使用此對象。 這種方式方法可用性不高,在大多數(shù)情況下應(yīng)該避免。

Ad-hoc 線程封閉下的一個特例適用于 volatile 變量。 只要確保 volatile 變量僅從單個線程寫入,就可以安全地對共享 volatile 變量執(zhí)讀 - 改 - 寫操作。在這種情況下,您將修改限制在單個線程以防止競爭條件,并且 volatile 變量的可見性保證確保其他線程看到最新值。

1.2 棧封閉

棧封閉將變量或?qū)ο蠓忾]在線程的棧中。這比 Ad-hoc 線程封閉強(qiáng)得多,因?yàn)樗ㄟ^定義堆棧本身中的變量狀態(tài)來進(jìn)一步限制對象的范圍。例如,請考慮以下代碼:

private long numberOfPeopleNamedJohn(List<Person> people) {
 List<Person> localPeople = new ArrayList<>();
 localPeople.addAll(people);
 return localPeople.stream().filter(person -> person.getFirstName().equals("John")).count();
}

在上面的代碼中,我們傳遞一個 person 對象的 list 但不直接使用它。 相反,我們創(chuàng)建自己的 list,該 list 是當(dāng)前正在執(zhí)行的線程的本地 list,并將變量 people中的所有 person 添加到 localPeople。由于我們僅在 numberOfPeopleNamedJohn方法中定義列表,這使得變量localPeople 受到堆棧隔離保護(hù),因?yàn)樗淮嬖谟谝粋€線程的堆棧上,因此任何其他線程都無法訪問它。這使得 localPeople 線程安全。 唯一需要注意的是,不應(yīng)該讓 localPeople 的作用于超過這個方法的范圍,以保證堆棧的隔離控制。在定義這個變量時(shí),應(yīng)該記錄或注釋為什么要定義這個變量,通常,只有在當(dāng)前開發(fā)人員的腦海中才不讓它超出方法的作用域,但是在將來,另一個開發(fā)人員可能會不知道為何如此設(shè)計(jì)而陷入困境。

1.3 ThreadLocal

ThreadLocal允許我們將每個線程 ID 與相應(yīng)對象的值相關(guān)聯(lián)。 它允許我們?yōu)椴煌木€程存儲不同的對象,并維護(hù)哪個對象對應(yīng)于哪個線程。它有 set 和 get 方法,這些方法為使用它的每個線程維護(hù)一個單獨(dú)的 value 副本。get() 方法總是返回從當(dāng)前正在執(zhí)行的線程傳遞給 set()的最新值。 我們來看一個例子:

public class ThreadConfinementUsingThreadLocal {
  public static void main(String[] args) {
    ThreadLocal<String> stringHolder = new ThreadLocal<>();
    Runnable runnable1 = () -> {
      stringHolder.set("Thread in runnable1");
      try {
        Thread.sleep(5000);
        System.out.println(stringHolder.get());
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };
    Runnable runnable2 = () -> {
      stringHolder.set("Thread in runnable2");
      try {
        Thread.sleep(2000);
        stringHolder.set("string in runnable2 changed");
        Thread.sleep(2000);
        System.out.println(stringHolder.get());
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };
    Runnable runnable3 = () -> {
      stringHolder.set("Thread in runnable3");
      try {
        Thread.sleep(5000);
        System.out.println(stringHolder.get());
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };
    Thread thread1 = new Thread(runnable1);
    Thread thread2 = new Thread(runnable2);
    Thread thread3 = new Thread(runnable3);
    thread1.start();
    thread2.start();
    thread3.start();
  }
}

在上面的例子中,我們使用相同的 ThreadLocal 對象 stringHolder 執(zhí)行了三個線程。正如你在這里看到的,我們首先在 stringHolder 對象的每個線程中設(shè)置一個字符串,使其包含三個字符串。然后,經(jīng)過一些暫停后,我們只更改了第二個線程的值。 以下是該程序的輸出:

string in runnable2 changed
Thread in runnable1
Thread in runnable3

正如您在上面的輸出中所看到的,線程2的字符串已更改,但線程1和線程3的字符串未受影響。如果我們在從 ThreadLocal 獲取特定線程的值之前沒有設(shè)置任何值,那么它返回null。 線程終止后,“ThreadLocal” 中特定于線程的對象就可以進(jìn)行垃圾回收了。

相關(guān)文章

  • java將數(shù)字價(jià)格轉(zhuǎn)換為中文大寫代碼示例(工具類)

    java將數(shù)字價(jià)格轉(zhuǎn)換為中文大寫代碼示例(工具類)

    這篇文章主要介紹了java將數(shù)字價(jià)格轉(zhuǎn)換為中文大寫的相關(guān)資料,在Java中實(shí)現(xiàn)將數(shù)字價(jià)格轉(zhuǎn)換為中文大寫需要將數(shù)字分解為各個部分(如個位、十位、百位等),并根據(jù)這些部分轉(zhuǎn)換為對應(yīng)的中文大寫數(shù)字,需要的朋友可以參考下
    2024-10-10
  • Spring整合MyBatis圖示過程解析

    Spring整合MyBatis圖示過程解析

    這篇文章主要介紹了Spring整合MyBatis圖示過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 最值得Java開發(fā)者收藏的網(wǎng)站

    最值得Java開發(fā)者收藏的網(wǎng)站

    這篇文章主要為大家分享了最值得Java開發(fā)者收藏的11個網(wǎng)站,幫助Java開發(fā)者提升編程能力
    2016-11-11
  • Java如何通過反射獲取Constructor、Field、Method對象

    Java如何通過反射獲取Constructor、Field、Method對象

    反射指的是對象的反向處理操作,根據(jù)對象取得對象的來源信息,在反射的世界里面,看重的不再是一個對象,而是對象身后的組成,下面這篇文章主要給大家介紹了關(guān)于Java如何通過反射獲取Constructor、Field、Method對象的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • maven項(xiàng)目打jar包并包含所有依賴詳細(xì)教程

    maven項(xiàng)目打jar包并包含所有依賴詳細(xì)教程

    maven打包生成的普通jar包,只包含該工程下源碼編譯結(jié)果,不包含依賴內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于maven項(xiàng)目打jar包并包含所有依賴的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)分析

    java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)分析

    這篇文章主要介紹了java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)分析,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例

    SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例

    這篇文章主要介紹了SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java的云打印Lodop

    Java的云打印Lodop

    這篇文章主要介紹了Java的云打印Lodop 的相關(guān)資料,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • java的異常與處理機(jī)制分析【附面試題】

    java的異常與處理機(jī)制分析【附面試題】

    這篇文章主要介紹了java的異常與處理機(jī)制,結(jié)合實(shí)例形式分析了Java異常與處理機(jī)制的概念、原理、相關(guān)操作技巧與注意事項(xiàng),并附帶面試題分析供大家參考,需要的朋友可以參考下
    2019-05-05
  • MyBatis-Plus介紹及Spring Boot 3集成指南

    MyBatis-Plus介紹及Spring Boot 3集成指南

    本文介紹了MyBatis-Plus的基本特性及其與Spring Boot 3的集成步驟,通過使用MyBatis-Plus,開發(fā)者可以快速地搭建和開發(fā)數(shù)據(jù)訪問層,同時(shí)提高代碼質(zhì)量和開發(fā)效率,感興趣的朋友一起看看吧
    2024-05-05

最新評論

万年县| 茶陵县| 奈曼旗| 进贤县| 凌源市| 柳河县| 文登市| 佛山市| 兴隆县| 黑山县| 体育| 抚远县| 方城县| 抚远县| 日喀则市| 通江县| 道孚县| 永昌县| 葫芦岛市| 祥云县| 张家港市| 鹤岗市| 扶绥县| 中江县| 通城县| 阿合奇县| 莆田市| 普洱| 金山区| 确山县| 凤山市| 乐东| 绍兴县| 凤阳县| 岳西县| 定陶县| 定陶县| 尼玛县| 中卫市| 赤壁市| 灌云县|