threadlocal是乙個執行緒級別的變數副本,它是對於執行緒隔離的,各個執行緒之間不能訪問非自己的threadlocal變數。
我們先來分析一下乙個優秀的id應該具備哪些特點?
為了保證id的全域性唯一,在生成的時候我們應該對其做一些併發安全的處理,不然很可能就會出現重複id,比如說id的序列號是遞增的,那麼如何去保證在多執行緒訪問情況下生成的id不重複呢?
我們最先想到的方式就是加鎖,每次只允許乙個執行緒去操作這個累加的變數,這樣自然是能夠做到的,但是鎖競爭會帶來額外的效能開銷,那有沒有不加鎖的方式可以保證在多執行緒的情況下生成唯一id呢?答案是肯定的,接下來我們看看如何使用threadlocal來實現無鎖化併發程式設計。
在發號器中最核心的**就是id序列號的生成,在本文中我也僅僅是對這一段進行分析(完整專案點這兒)
打個比方假如我們能夠生成100個id,1~100,我們有兩個執行緒,第乙個執行緒只生成1,3,5…這樣的id,第二個執行緒只生成2,4,6…這樣的id,從理論上來說,這樣的併發是不會重複的。
那麼我們的問題就轉化成了如何去分配生成的id段,話不多說,直接上**講解吧
public
class
sender};
//用執行緒id作為起始值
private
static
final threadlocal
target=
newthreadlocal
()};
//用執行緒池中的執行緒去生成id
private
static future
doget()
);}public
static
long
get(
)catch
(interruptedexception e)
catch
(executionexception e)
return0;
}}
我們來測試一下是否會出現重複id
public
class
test
catch
(interruptedexception e)
catch
(brokenbarrierexception e)
//把生成的id放到set中去
for(
int j =
0; j <
1000000
; j++)}
).start()
;}//主線程睡眠20s等待程式跑完
thread.
sleep
(20000);
//輸出id個數,如果size==執行緒數*單個執行緒生成的id數則認為是執行緒安全的
system.out.
println
(set.
size()
);}}
結果如下通過這種為執行緒劃分工作範圍的方式,我們可以利用threadlocal做到無鎖化的併發程式設計10000000
聊聊ThreadLocal原始碼 基於JDK1 8
原文 主要方法 public t get return setinitialvalue public void set t value 下面 時樓主認為threadlocal中比較重要的,還是比較容易看懂的,就不在一一細說 public class threadlocal 除非執行緒先前呼叫了方法,...
關於無鎖佇列(基於陣列)
鎖的底層必然有著原子操作,而其設計為通用場景使用,我們拋棄鎖的使用,直接從更細粒度來使用原子操作確保佇列的一致性 稱為無鎖佇列 什麼樣的佇列可以支援併發的多生產者多消費者?確保併發的copy過程互不影響 確保併發的指標更新操作原子不丟失。指標操作無非是值的操作,不存在順序問題 如何確保上述兩點?最粗...
基於PCDN技術的無延時直播方案
摘要 2018亞太cdn峰會在北京隆重召開,在4月12日上午的運營商論壇中,阿里雲邊緣計算團隊高階技術專家張士波進行了 基於pcdn技術的無延時直播方案 的主題演講。本文為演講內容。當大家談到直播,一般很驚訝於直播近幾年來發展的規模,尤其是2016到2017年直播使用者增長速度達到了22.6 使用者...