一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 基于多線程并發(fā)的常見問題(詳解)

基于多線程并發(fā)的常見問題(詳解)

2021-01-15 14:17tonghun Java教程

下面小編就為大家?guī)硪黄诙嗑€程并發(fā)的常見問題(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一 概述

1.volatile

保證共享數(shù)據(jù)一旦被修改就會(huì)立即同步到共享內(nèi)存(堆或者方法區(qū))中。

2.線程訪問堆中數(shù)據(jù)的過程

線程在棧中建立一個(gè)數(shù)據(jù)的副本,修改完畢后將數(shù)據(jù)同步到堆中。

3.指令重排

為了提高執(zhí)行效率,CPU會(huì)將沒有依賴關(guān)系的指令重新排序。如果希望控制重新排序,可以使用volatile修飾一個(gè)變量,包含該變量的指令前后的指令各自獨(dú)立排序,前后指令不能交叉排序。

二 常見問題及應(yīng)對(duì)

1.原子性問題

所謂原子性,指的是一個(gè)操作不可中斷,即在多線程并發(fā)的環(huán)境下,一個(gè)操作一旦開始,就會(huì)在同一個(gè)CPU時(shí)間片內(nèi)執(zhí)行完畢。如果同一個(gè)線程的多個(gè)操作在不同的CPU時(shí)間片上執(zhí)行,由于中間出現(xiàn)停滯,后面的操作在執(zhí)行時(shí)可能某個(gè)共享數(shù)據(jù)被其他線程修改,而該修改并未同步到當(dāng)前線程中,導(dǎo)致當(dāng)前線程操作的數(shù)據(jù)與實(shí)際不符,這種由于執(zhí)行不連貫導(dǎo)致的數(shù)據(jù)不一致問題被稱作原子性問題。

2.可見性問題

可見性問題的出現(xiàn)與線程訪問共享數(shù)據(jù)的方式有關(guān)。線程訪問堆(方法區(qū))中的變量時(shí),先在棧中建立一個(gè)變量的副本,修改后再同步到堆中。如果一個(gè)線程剛建立副本,這時(shí)另一線程修改了變量,尚未同步到堆中,這時(shí)就會(huì)出現(xiàn)兩個(gè)線程操作同一變量的同一種狀態(tài)的現(xiàn)象,比如i=9,變量i的初始值為9,每一個(gè)線程的操作都是減1。兩個(gè)線程A與B同時(shí)訪問變量,B先執(zhí)行i-1,在將結(jié)果i=8同步到堆中前,A線程也執(zhí)行i-1,這時(shí)i=9的狀態(tài)就被執(zhí)行兩次,出現(xiàn)線程安全問題。

線程安全問題產(chǎn)生的原因:一個(gè)線程對(duì)共享數(shù)據(jù)的修改不能立即為其他線程所見。

volatile提供了一種解決方案:

一旦一個(gè)線程修改了被volatile修飾的共享數(shù)據(jù),這種修改就會(huì)立即同步到堆中,這樣其他數(shù)據(jù)從堆中訪問共享數(shù)據(jù)時(shí)始終獲得的是在多個(gè)線程中的最新值。

volatile的缺陷:

volatile只能保證一個(gè)線程從堆中獲取數(shù)據(jù)時(shí)獲取的是當(dāng)前所有線程中的最新值,假如一個(gè)線程已經(jīng)從堆中復(fù)制了數(shù)據(jù),在操作完成前,其他線程修改了數(shù)據(jù),修改后的數(shù)據(jù)并不會(huì)同步到當(dāng)前線程中。

3.有序性問題

為了提高執(zhí)行效率,CPU會(huì)對(duì)那些沒有依賴關(guān)系的指令重新排序,重新排序后的執(zhí)行結(jié)果與順序執(zhí)行結(jié)果相同。

例如,在源代碼中:

?
1
2
int i=0;
int y=1;

CPU在執(zhí)行時(shí)可能先執(zhí)行“int y=1;”,接著執(zhí)行“int i=0;”,執(zhí)行結(jié)果與順序執(zhí)行結(jié)果相同。

指令重排在單線程環(huán)境下是安全的,在多線程環(huán)境下就可能出現(xiàn)問題。比如:

線程A:

?
1
2
s=new String("sssss");//指令1
flag=false;//

指令2線程B:

?
1
2
3
while(flag){
doSome();
}

s.toUpperCase();//指令3如果線程A順序執(zhí)行,即執(zhí)行指令1,再執(zhí)行指令2,線程B的執(zhí)行不會(huì)出現(xiàn)問題。指令重排后,假如線程A先執(zhí)行指令2,這時(shí)flag=true,切換到線程2,終止循環(huán),執(zhí)行指令3,由于s對(duì)象尚未創(chuàng)建就會(huì)出現(xiàn)空指針異常。

有序性問題產(chǎn)生的原因:

一個(gè)線程對(duì)其他線程對(duì)共享數(shù)據(jù)的修改操作有順序要求,比如線程B要求線程A先執(zhí)行指令1,再執(zhí)行指令2,由于指令重排,實(shí)際并未按照要求的順序執(zhí)行,這時(shí)就出現(xiàn)了線程安全問題。

解決思路:

1.利用同步機(jī)制,使得同一時(shí)間只有一個(gè)線程可以訪問共享數(shù)據(jù),效率低。

2.使用volatile,一個(gè)指令包含volatile修飾的變量,那么這條指令的執(zhí)行順序不變,該指令前后的指令可以各自獨(dú)立重排,無法交叉重排。

以上這篇基于多線程并發(fā)的常見問題(詳解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/tonghun/p/7086251.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美一区二区日韩一区二区 | 超大阿力gaysex | 日本美女视频韩国视频网站免费 | 欧美图片小说 | 福利片成人午夜在线 | 美女一级ba大片免色 | 色吧五月婷婷 | 国产精品成人一区二区1 | 国产精品视频播放 | 冰山美人调教耻辱h | 亚洲精品AV无码永久无码 | 美女的让男人桶爽免费看 | 女人张开腿让男人桶爽 | 9191久久 | 天天综合亚洲 | 免费理伦片手机在线播放 | 欧美人禽杂交狂配无删完整 | 精品在线播放视频 | 欧美日韩免费一区二区在线观看 | 日本午夜影院 | 国产一级在线观看视频 | 69热精品视频在线看影院 | 亚洲天堂精品视频 | 亚欧毛片基地国产毛片基地 | 国产成人精品一区二三区 | www黄| 亚洲福利精品电影在线观看 | 天堂bt在线| 久久精品嫩草影院免费看 | 国产福利在线观看第二区 | 久久中文骚妇内射 | 日韩精品一区二区三区中文字幕 | 色综合天天综合网看在线影院 | 亚瑟天堂久久一区二区影院 | 国产色资源 | 果冻传媒在线观看的 | china外卖员gay帮口 | 俄罗斯一级在线播放 | www.男人的天堂.com | 欧美撒尿屁股嘘嘘撒尿 | 国产精品久久久久久福利 |