java并发编程笔记_java并发编程笔记(一)——并发编程简介
java并發(fā)編程筆記(一)——簡介
線程不安全的類示例
public class CountExample1 {
// 請求總數(shù)
public static int clientTotal = 5000;
// 同時并發(fā)執(zhí)行的線程數(shù)
public static int threadTotal = 200;
public static int count = 0;
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count); //最終得到的結果是小于5000的
}
private static void add() {
count++;
}
}
并發(fā):
同時擁有兩個或者多個線程,如果程序在單核處理器上運行,多個線程將交替的換入換出內(nèi)存,這些線程是同時“存在”的,每個線程都處于執(zhí)行過程中的某個狀態(tài),如果運行在多核處理器上,程序中的每個線程都將分配到一個處理器核上,因此可以同時運行。
多個線程操作相同的資源,保證線程安全,合理使用資源
高并發(fā)(High Concurrency):
高并發(fā)是互聯(lián)網(wǎng)分布式系統(tǒng)架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統(tǒng)能夠同時并行處理很多請求。
java 內(nèi)存模型(Java Memory Model,JMM)
java堆
可以在運行時動態(tài)的分配內(nèi)存大小;
由于在運行時動態(tài)的分配大小,所以他的存取速度很慢;
java棧
存取速度很快,僅次于計算機的寄存器,棧里的數(shù)據(jù)都是可以共享的;
棧由于存放的數(shù)據(jù)大小與生存期是要求確定的,所以缺少一定的靈活性;
java線程引用對象的圖示
cpu訪問主存圖示
當兩個線程同時訪問一個對象時,這兩個線程持有的是這個對象的私有拷貝。
cpu模型圖
cpu訪問寄存器的速度遠大于在主存上的讀取速度
由于計算機的存儲設備與處理器的處理速度有好幾個數(shù)據(jù)量級的差距,所以存在了高速緩存區(qū)
java內(nèi)存模型抽象結構圖
java內(nèi)存模型-同步八種操作
lock(鎖定):作用于主內(nèi)存的變量,把一個變量標識為一條線程獨占狀態(tài)
unlock(解鎖):作用于主內(nèi)存的變量,把一個處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定
read(讀取):作用主內(nèi)存的變量,把一個變量值由主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load使用
load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中
use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量值傳遞給執(zhí)行引擎
assign(賦值):作用于工作內(nèi)存的變量,它把一個從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量
store(存儲):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量的值傳送到主存中,以便隨后的write的操作
write(寫入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個變量的值傳送到主內(nèi)存的變量中
java內(nèi)存模型-同步規(guī)則
如果要把一個變量從主存中復制到工作內(nèi)存,就需要按順序的執(zhí)行read和load操作,如果把變量從工作內(nèi)存中同步回主內(nèi)存中,就要按順序的執(zhí)行store和write操作。但java內(nèi)存模型只要求上述操作必須按順序執(zhí)行,而沒有保證必須是連續(xù)執(zhí)行
不允許read和load、store和write操作之一單獨出現(xiàn)
不允許一個線程丟棄它的最近assign的操作,即變量在工作內(nèi)存中改變了之后,必須同步到主內(nèi)存中
不允許一個線程無原因的(沒有發(fā)生過任何assign操作)把數(shù)據(jù)從工作內(nèi)存同步回主內(nèi)存中
一個新的變量只能在主內(nèi)存中誕生,不允許在工作內(nèi)存中直接使用一個未被初始化(load和assign)的變量。即就是對一個變量實施use和store操作之前,必須先執(zhí)行過了assign和load操作
一個變量在同一時刻只允許一條線程對其進行l(wèi)ock操作,但lock操作可以被同一條線程重復執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同次數(shù)的unlock操作,變量才會被解鎖,lock和unlock必須成對出現(xiàn)
如果對一個變量執(zhí)行l(wèi)ock操作,將會清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個變量前需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值
如果一個變量事先沒有被lock操作鎖定,則不允許對它執(zhí)行unlock操作,也不允許去unlock一個被其他線程鎖定的變量
對一個變量執(zhí)行unlock操作之前,必須先把此變量同步到主內(nèi)存中(執(zhí)行store和write操作)
并發(fā)的優(yōu)勢和風險
優(yōu)勢
同時處理多個請求,響應更快,負責的操作可以分成多個進程同時進行
程序設計在某些情況下更簡單,也可以有更多的選擇
CPU能夠在等待IO的時候做一些其他的事情
風險
多個線程共享數(shù)據(jù)可能會產(chǎn)生與期望不相符的結果
某個操作無法繼續(xù)進行下去時,就會發(fā)生活躍性問題,比如死鎖、饑餓等問題
線程過多時會使得CPU頻繁切換,調(diào)度時間增多,同步至機制;消耗過多內(nèi)存
總結
CPU多級緩存:緩存一致性,亂序執(zhí)行優(yōu)化
java內(nèi)存模型:JMM規(guī)定、抽象結構、同步八中操作及規(guī)則
java并發(fā)的優(yōu)勢與風險
總結
以上是生活随笔為你收集整理的java并发编程笔记_java并发编程笔记(一)——并发编程简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 战魂铭人马甲裙怎么获得
- 下一篇: 逻辑短路 java_逻辑操作符中的短路现