線程安全代碼到底是怎么編寫的?
從根源上思考

關(guān)你什么屁事
維護(hù)公共場(chǎng)所秩序
線程私有資源,沒有線程安全問題 共享資源,線程間以某種秩序使用共享資源也能實(shí)現(xiàn)線程安全。
什么是線程安全
int func() {int a = 1;int b = 1;return a + b;}

線程私有資源

線程間共享數(shù)據(jù)
用于動(dòng)態(tài)分配內(nèi)存的堆區(qū),我們用C/C++中的malloc或者new就是在堆區(qū)上申請(qǐng)的內(nèi)存 全局區(qū),這里存放的就是全局變量 文件,我們知道線程是共享進(jìn)程打開的文件

只使用線程私有資源
int func() {int a = 1;int b = 1;return a + b;}

線程私有資源+函數(shù)參數(shù)
int func(int num) {num++;return num;}

int func(int* num) {++(*num);return *num;}
int global_num = 1;int func(int* num) {++(*num);return *num;}// 線程1void thread1() {func(&global_num);}// 線程2void thread1() {func(&global_num);}


使用全局資源
int global_num = 100; //初始化一次,此后沒有其它代碼修改其值int func() {return global_num;}

int global_num = 100;int func() {++global_num;return global_num;}
線程局部存儲(chǔ)
__thread int global_num = 100;int func() {++global_num;return global_num;}
global_num是全局變量 global_num是線程私有的

函數(shù)返回值
int func() {int a = 100;return a;}
int* func() {static int a = 100;return &a;}

class S {public:static S& getInstance() {static S instance;return instance;}private:S() {}// 其它省略}
調(diào)用非線程安全代碼
int global_num = 0;int func() {++global_num;return global_num;}
int funcA() {mutex l;l.lock();func();l.unlock();}
int func(int *num) {++(*num);return *num;}
void funcA() {int a = 100;func(&a);}
如何實(shí)現(xiàn)線程安全
不使用任何全局資源,只使用線程私有資源,這種通常被稱為無狀態(tài)代碼 線程局部存儲(chǔ),如果要使用全局資源,是否可以聲明為線程局部存儲(chǔ),因?yàn)檫@種變量雖然是全局的,但每個(gè)線程都有一個(gè)屬于自己的副本,對(duì)其修改不會(huì)影響到其它線程 只讀,如果必須使用全局資源,那么全局資源是否可以是只讀的,多線程使用只讀的全局資源不會(huì)有線程安全問題。 原子操作,原子操作是說其在執(zhí)行過程中是不可能被其它線程打斷的,像C++中的std::atomic修飾過的變量,對(duì)這類變量的操作無需傳統(tǒng)的加鎖保護(hù),因?yàn)镃++會(huì)確保在變量的修改過程中不會(huì)被打斷。我們常說的各種無鎖數(shù)據(jù)結(jié)構(gòu)通常是在這類原子操作的基礎(chǔ)上構(gòu)建的 。 同步互斥,到這里也就確定了你必須要以某種形式使用全局資源,那么在這種情況下公共場(chǎng)所的秩序必須得到維護(hù),那么怎么維護(hù)呢?通過同步或者互斥的方式,這是一大類問題。
總結(jié)
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號(hào)
好文章,我在看??
評(píng)論
圖片
表情
