bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

Java并發中如何實現線程封閉

這篇文章給大家分享的是有關Java并發中如何實現線程封閉的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

發展壯大離不開廣大客戶長期以來的信賴與支持,我們將始終秉承“誠信為本、服務至上”的服務理念,堅持“二合一”的優良服務模式,真誠服務每家企業,認真做好每個細節,不斷完善自我,成就企業,實現共贏。行業涉及廣告制作等,在成都網站建設、營銷型網站建設、WAP手機網站、VI設計、軟件開發等項目上具有豐富的設計經驗。

線程封閉基礎知識點

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

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

1:ad-hoc線程封閉

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

2:棧封閉

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

3:ThreadLocal封閉

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

1. 線程封閉

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

Java 語言本身沒有任何強制執行線程封閉的方法。線程封閉是通過不允許多個線程同時使用同一個狀態的方式的程序設計來實現的,因此由程序實現強制執行。 幾種類型的線程封閉,如下所示:

1.1 Ad-Hoc 線程封閉

Ad-hoc 線程封閉描述了線程封閉的方式,由開發人員或從事該項目的開發人員確保僅在單個線程內使用此對象。 這種方式方法可用性不高,在大多數情況下應該避免。

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

1.2 棧封閉

棧封閉將變量或對象封閉在線程的棧中。這比 Ad-hoc 線程封閉強得多,因為它通過定義堆棧本身中的變量狀態來進一步限制對象的范圍。例如,請考慮以下代碼:

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 但不直接使用它。 相反,我們創建自己的 list,該 list 是當前正在執行的線程的本地 list,并將變量 people中的所有 person 添加到 localPeople。由于我們僅在 numberOfPeopleNamedJohn方法中定義列表,這使得變量localPeople 受到堆棧隔離保護,因為它只存在于一個線程的堆棧上,因此任何其他線程都無法訪問它。這使得 localPeople 線程安全。 唯一需要注意的是,不應該讓 localPeople 的作用于超過這個方法的范圍,以保證堆棧的隔離控制。在定義這個變量時,應該記錄或注釋為什么要定義這個變量,通常,只有在當前開發人員的腦海中才不讓它超出方法的作用域,但是在將來,另一個開發人員可能會不知道為何如此設計而陷入困境。

1.3 ThreadLocal

ThreadLocal允許我們將每個線程 ID 與相應對象的值相關聯。 它允許我們為不同的線程存儲不同的對象,并維護哪個對象對應于哪個線程。它有 set 和 get 方法,這些方法為使用它的每個線程維護一個單獨的 value 副本。get() 方法總是返回從當前正在執行的線程傳遞給 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 執行了三個線程。正如你在這里看到的,我們首先在 stringHolder 對象的每個線程中設置一個字符串,使其包含三個字符串。然后,經過一些暫停后,我們只更改了第二個線程的值。 以下是該程序的輸出:

string in runnable2 changed
Thread in runnable1
Thread in runnable3

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

感謝各位的閱讀!關于“Java并發中如何實現線程封閉”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

當前題目:Java并發中如何實現線程封閉
路徑分享:http://vcdvsql.cn/article8/pocoop.html

成都網站建設公司_創新互聯,為您提供網站收錄、營銷型網站建設、定制網站、網站排名、企業建站關鍵詞優化

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都定制網站網頁設計