出去打工和儿子租房
  • ThreadLocal是雞肋嗎?

    2021-12-08 12:18發布

    多線程,訪問同一個共享變量的時候容易出現并發問題,特別是多個線程對一個變量進行寫入的時候,為了保證線程安全,一般使用者在訪問共享變量的時候需要進行額外的同步措施才能保證線程安全性。ThreadLocal是除了加鎖這種同步方式之外的一種保證一種規避多線程訪問出現線程不安全的方法,當我們在創建一個變量后,如果每個線程對其進行訪問的時候訪問的都是線程自己的變量這樣就不會存在線程不安全問題。


    一、 ThreadLocal的常見使用場景?

    A:每個線程中需要維護1個不同的副本, 但這個副本可能是某一個時刻一起塞入每個線程的, 只不過之后該副本的變化 不再受其他線程的影響。

    常見場景有連接器管理模塊connectorManager, 每個線程持有的connect變量是單獨使用的,不會互相影響或者需要加鎖。原因就是將其作為副本放入每個線程,當線程啟動連接或者關閉時,不影響其他線程里的getConnect方法。


    二、 ThreadLocal和Synchronized關鍵字的區別?

    Synchronized是用時間的消耗,來換取數據同步以及互不沖突

    ThreadLocal則是用空間的消耗,來換取數據之間互不沖突(不涉及同步)


    三、TheadLocal在每個線程中是以什么形式存儲的? 原理是什么


    Java并發編程:深入剖析看完后用我自己的話總結一下就是:


    1. 在某個線程中調用 某threadlocal.set(value)時, 其實就是在該線程中新建了1個threalocalMap, 然后把threadLocal作為鍵,value作為值,放進本線程的threalocalMap中。

    2. 當在線程中調用threadlocal.get()的時候,就是從線程的threadLocalMap中獲取這個threadLocal對應的值
      如果get不到,則可以通過自定義initValue方法生成一個threadLocal的默認值

    四、下面這個代碼會報什么錯?(例子改編自上面鏈接的文章)

    在Thread1中,會報空指針, 因為調用get之前沒有做過set, 此時做get會報錯。

    一種方式改成這樣:


    另一種是給stringLocal設置默認值,這種一般用于能直接根據線程推導出初始值的情況

    正確set之后, 答案就會返回thread0和thread1, 且后續怎么set,兩邊都不會互相影響各自的threadLocal,雖然看起來是都用的是同一個Test里的成員。


    出去打工和儿子租房