人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統(tǒng) > 硬件軟件教程 > 詳細頁面

JAVA并發(fā)編程階段,處理死鎖問題與線程局部原理區(qū)分的概述

JAVA并發(fā)編程階段,處理死鎖問題與線程局部原理區(qū)分的概述

更新時間:2023-06-21 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

根據(jù)運行的環(huán)境,操作系統(tǒng)可以分為桌面操作系統(tǒng),手機操作系統(tǒng),服務(wù)器操作系統(tǒng),嵌入式操作系統(tǒng)等。

避免線程死鎖_java線程死鎖怎么解決_java多線程避免死鎖

讓我們首先看一下死鎖的概念: 一組相互競爭的線程正在互相等待,并導(dǎo)致“永久”阻塞. 我們稱這為僵局. 如果存在死鎖,則必須有一個活鎖. 是活鎖嗎?也就是說,任務(wù)和執(zhí)行程序都不會被阻塞. 由于不滿足某些條件,因此重試->嘗試執(zhí)行->執(zhí)行失敗的過程稱為活動鎖.

只要滿足以下四個條件,就不可避免地會發(fā)生死鎖:

根據(jù)上述四個死鎖條件,只需破壞其中一個條件,就不會發(fā)生死鎖.

其作用是使線程的執(zhí)行結(jié)果對后續(xù)線程的訪問可見.

ThreadLocal實際上是一種線程隔離機制,用于確保在多線程環(huán)境中訪問共享變量的安全性.

 /**
* Sets the current thread's copy of this thread-local variable
* to the specified value.  Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
*        this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
 

當?shù)貓D不為空時,執(zhí)行map.set(this,value)方法,代碼如下:

private void set(ThreadLocal<?> key, Object value) {
// We don't use a fast path as with get() because it is at
// least as common to use set() to create new entries as
// it is to replace existing ones, in which case, a fast
// path would fail more often than not.
Entry[] tab = table;
int len = tab.length;
//根據(jù)哈希碼和數(shù)組長度求得元素的放置位置,即Entry數(shù)組的下標
int i = key.threadLocalHashCode & (len-1);
//從i開始遍歷到數(shù)組的最后一個Entry(進行線性探索)
for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get();
//如果key相等,就覆蓋value
if (k == key) {
e.value = value;
return;
}
//如果key為空,用新的key,value,同時清理歷史key=null(弱引用)的舊數(shù)據(jù)
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
//如果超過設(shè)置的閥值,則需要進行擴容
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
 

上面的源代碼中使用了線性檢測方法來解決哈希沖突問題.

java線程死鎖怎么解決_避免線程死鎖_java多線程避免死鎖

那么什么是線性檢測?

線性檢測是一種開放式尋址策略. 哈希表通過密鑰直接訪問數(shù)據(jù)結(jié)構(gòu),并且密鑰通過哈希函數(shù)映射到哈希表中某個位置的訪問記錄,從而加快了搜索速度. 該存儲記錄稱為哈希表(也稱為哈希表).

有兩種方法可以解決此沖突:

一個流行的解釋是: 當我們下蹲并發(fā)現(xiàn)坑被占用時,我們會尋找下一個坑. 如果后面的坑是空的,那么它將被占用;如果后一個坑被占用,則繼續(xù)遍歷后坑直到找到可用的坑為止,否則您將一直保持holding陷.

private void replaceStaleEntry(ThreadLocal<?> key, Object value,
int staleSlot) {
Entry[] tab = table;
int len = tab.length;
Entry e;
// Back up to check for prior stale entry in current run.
// We clean out whole runs at a time to avoid continual
// incremental rehashing due to garbage collector freeing
// up refs in bunches (i.e., whenever the collector runs).
//向前掃描,查找最前一個無效的slot
int slotToExpunge = staleSlot;
for (int i = prevIndex(staleSlot, len);
(e = tab[i]) != null;
i = prevIndex(i, len))
if (e.get() == null)
//通過循環(huán)遍歷,可以定位到最前面的一個無效的slot
slotToExpunge = i;
// Find either the key or trailing null slot of run, whichever
// occurs first
//從i開始遍歷到數(shù)組的最后一個Entry(進行線性探索)
for (int i = nextIndex(staleSlot, len);
(e = tab[i]) != null;
i = nextIndex(i, len)) {
ThreadLocal<?> k = e.get();
// If we find key, then we need to swap it
// with the stale entry to maintain hash table order.
// The newly stale slot, or any other stale slot
// encountered above it, can then be sent to expungeStaleEntry
// to remove or rehash all of the other entries in run.
//找到匹配的key
if (k == key) {
//更新對應(yīng)的slot對應(yīng)的value
e.value = value;
//與無效的slot進行替換
tab[i] = tab[staleSlot];
tab[staleSlot] = e;
// Start expunge at preceding stale entry if it exists
////如果最早的一個無效的slot和當前的staleSlot相等,則從i作為清理的起點
if (slotToExpunge == staleSlot)
slotToExpunge = i;
//從slotToExpunge開始做一次連續(xù)的清理
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
return;
}
// If we didn't find stale entry on backward scan, the
// first stale entry seen while scanning for key is the
// first still present in the run.
//如果當前的slot已經(jīng)無效,并且向前掃描過程中沒有無效slot,則更新slotToExpunge為當前位置
if (k == null && slotToExpunge == staleSlot)
slotToExpunge = i;
}
// If key not found, put new entry in stale slot
//如果key對應(yīng)的value在entry中不存在,則直接放一個新的entry
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);
// If there are any other stale entries in run, expunge them
//如果有任何一個無效的slot,則做一次清理
if (slotToExpunge != staleSlot)
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
}
 

ThreadLocal的源代碼如下:

//HASH_INCREMENT是為了讓哈希碼能均勻的分布在2的N次方的數(shù)組里
private static final int HASH_INCREMENT = 0x61c88647;
/**
* Returns the next hash code.
*/
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
 

它定義了一個魔術(shù)值HASH_INCREMENT = 0x61c88647. 對于實例變量threadLocalHashCode,無論何時創(chuàng)建ThreadLocal實例,此值都將為getAndAdd(0x61c88647).

HASH_INCREMENT在某種算法的幫助下,哈希碼可以以2的冪次均勻地分布到N次方,這確保了哈希表的分散性并降低了沖突的可能性. 讓我們編寫一些測試代碼:

public class FibonacciHash {
private static final int HASH_INCREMENT = 0x61c88647;
public static void main(String[] args) {
magicHash(16);
magicHash(32);
}
private static void magicHash(int size) {
int hashCode = 0;
for (int i = 0; i < size; i++) {
hashCode = i * HASH_INCREMENT + HASH_INCREMENT;
System.out.print((hashCode & (size - 1)) + " ");
}
System.out.println("");
}
}
 

執(zhí)行main()方法的結(jié)果:

避免線程死鎖_java線程死鎖怎么解決_java多線程避免死鎖

7 14 5 12 3 10 1 8 15 6 13 4 11 2 9 0
7 14 21 28 3 10 17 24 31 6 13 20 27 2 9 16 23 30 5 12 19 26 1 8 15 22 29 4 11 18 25 0
 

生成的哈希碼的分布確實非常均勻,并且沒有沖突.

前端架構(gòu)設(shè)計: 模型驅(qū)動的前端開發(fā)JAVA并發(fā)編程的漸進文章,探討線程安全volatile關(guān)鍵字如何確保可見性數(shù)據(jù)鏈接層eBPF技術(shù)的高性能ACL瀏覽器架構(gòu),單線程js,事件循環(huán),消息隊列,宏任務(wù)和微任務(wù)

Web前端技術(shù)交流網(wǎng)絡(luò):

我想創(chuàng)建一個函數(shù),如果一個單詞中的所有字母都按字母順序出現(xiàn),則返回true.

但是通話后java多線程避免死鎖,它一直向我返回True,我希望其他人看看出了什么問題

”`

def abcd():

a =“ abcdc”

fo ...

Ajax請求中的get和post有什么區(qū)別? Ajax request中的get和post有什么區(qū)別? Ajax request中的get和post有什么區(qū)別? Ajax request中的get和post有什么區(qū)別?請求Ajax時獲取并獲取...

java線程死鎖怎么解決_避免線程死鎖_java多線程避免死鎖

#我下載了vue-element-admin,并在本地npm insatall之后的npm run dev之后報告了一個錯誤. 刪除node_modules后,無法進行重置.

C: UsersLe’novoDesktopproj ...

我最近學(xué)習(xí)了Java語言. 我是新手. 我想使用TCP套接字進行網(wǎng)絡(luò)編程,以使服務(wù)器接受來自客戶端的文件,但是遇到錯誤. 有人知道如何解決嗎?

”`

//這是服務(wù)器端代碼

公共課...

JS中“ ==”和“ ===”之間的區(qū)別JS中“ ==”和“ ===”之間的區(qū)別JS中“ ==”和“ ===”之間的區(qū)別“ = =“和” ===“之間的區(qū)別JS中” ==“和” ===“之間的區(qū)別JS中” ==“和” ===“之間的區(qū)別

在緊急購買功能中,為了防止產(chǎn)品超賣,如果使用redis鎖,則會引入一個鎖. 這里的問題是它是否是...繼續(xù)閱讀關(guān)于同時購買獲得鎖的問題

給出以下代碼,如果__name__ ==“ __main__”怎么辦?

#線程示例

導(dǎo)入時間,線程

java多線程避免死鎖_避免線程死鎖_java線程死鎖怎么解決

def myfunction(字符串,睡眠時間,鎖定java多線程避免死鎖,* args):

為True時:

lock.acquire()

...

...請參閱有關(guān)302303的文章...繼續(xù)閱讀有關(guān)HTTP響應(yīng)代碼302303307的兩個問題

**我在Github上提取了一組標準Vue模板以進行本地開發(fā),并且工作正常. 也就是說,Chrome瀏覽器的“源”模塊無法準確定位源代碼. 如果找不到,則無法對其進行調(diào)試.

**

![圖片描述](...

以前,使用全局變量在不同路徑之間共享參數(shù). 我想問一下打開多線程后該怎么辦? @ app.r ...繼續(xù)閱讀flask使用多個線程后,每個線程中的不同路由如何共享參數(shù)?

在Mac上使用Command + Shift + B快捷鍵構(gòu)建.net核心解決方案時,報告了錯誤: bin / bash: dotnet: 找不到命令te

![圖片描述]()![圖片描述](…


本文來自本站,轉(zhuǎn)載請注明本文網(wǎng)址:
http://www.pc-fly.com/a/jisuanjixue/article-284711-1.html



溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 惠水县| 孟州市| 怀仁县| 盘山县| 津南区| 凯里市| 九江市| 类乌齐县| 正镶白旗| 桂林市| 沙田区| 柯坪县| 临漳县| 乡城县| 肇东市| 文安县| 五台县| 饶河县| 泰顺县| 大理市| 闻喜县| 淮安市| 乌鲁木齐市| 邢台市| 尼勒克县| 礼泉县| 东兴市| 阿拉尔市| 鄄城县| 蒙城县| 阿坝县| 长泰县| 布拖县| 德昌县| 和顺县| 光山县| 海林市| 太保市| 共和县| 丘北县| 卢龙县|