原子性 - 鎖
原子性:互斥性。能保證同一時刻只有一個線程操作的,除了atomic包內的類,另個鎖。
鎖:
synchronized, 鎖關鍵字,依賴jvm實現,這個關鍵字作用對象的作用範圍內,同一時刻只能有一個線程操作的,
Lock:依賴特殊的cpu指令,代碼實現,ReentrantLock
synchronized
synchronized同步鎖,修飾4中對象
(1)修飾一個代碼塊,被修飾的範圍叫做同步語句塊,作用於調用對象,同一個對象調用是互斥的;
代碼演示:
package com.mmall.concurrency.sync;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
/**
* @Author: wn
* @Description: synchronized ,
* @Date: Created in 2019/1/12 15:05
*/
@Slf4j
public class SynchronizedExample1 {
// 修飾一個代碼塊,被修飾的範圍叫做同步語句塊,作用於調用對象
public void test1() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
log.info("test1 {}", i);
}
}
}
// 修飾一個方法,,被修飾的範圍叫做同步方法,作用於調用對象
public synchronized void test2() {
for (int i = 0; i < 10; i++) {
log.info("test2 {}", i);
}
}
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = new ThreadPoolExecutor(2, 5, 3000,
TimeUnit.MINUTES, new LinkedBlockingDeque<>(), new ThreadPoolExecutor.AbortPolicy());
// log.info("修飾一個代碼塊,被修飾的範圍叫做同步語句塊,作用於調用對象,同一個對象調用是互斥的:");
// executorService.execute(() -> {
// example1.test1();
// });
// executorService.execute(() -> {
// example1.test1();
// });
log.info("修飾一個方法,,被修飾的範圍叫做同步方法,作用於調用對象,同一個對象調用是互斥的:");
executorService.execute(() -> {
example1.test2();
});
executorService.execute(() -> {
example1.test2();
});
// log.info("調用不同的代碼塊,各自執行,互不影響");
// executorService.execute(() -> {
// example1.test1(1);
// });
// executorService.execute(() -> {
// example2.test2(2);
// });
}
}
執行結果:
(2) 修飾一個方法,,被修飾的範圍叫做同步方法,作用於調用對象,同一個對象調用是互斥的
執行結果:
(3)修飾一個類,作用對象是類的所有對象
運行結果:
(4)修飾一個靜態方法,被修飾的範圍叫做靜態同步方法,作用對象是類的所有對象
運行結果:
synchronize 實現計數器
執行結果:
5000
原子性 - 對比 鎖區別
synchronize :不可中斷,一旦執行到同步代碼時,就必須執行完,適合競爭不激烈的情況,可讀性較好,當競爭很激烈時,synchronize 的性能下降非常快
Lock:可中斷,調用unlock()可以中斷線程執行,競爭激烈時保持常態,
atomic : 競爭激烈時也能維持常態,比Lock 性能好,缺點就是隻能同步一個值