`synchronized java 同步`的關鍵字,其典型的作用域如下所示. 1 對象鎖 1.1 代碼塊修飾(對象) 此時, 用於保證 函數中的被 大括弧包裹的代碼同步執行. 作用的對象為 的對象實例,例如 函數中的 以及 . Tips: 1. 若在多個線程中被調用,其輸出順序將保證同步,按照 的 ...
synchronized
是java
中用於同步
的關鍵字,其典型的作用域如下所示.
1 對象鎖
@Slf4j
public class SynchronizedExample1 {
private final int loopNum = 20;
// 修飾一個代碼塊
private void test1(int j) {
synchronized (this) {
for (int i = 0; i < loopNum; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修飾一個方法
private synchronized void test2(int num) {
for (int i = 0; i < loopNum; i++) {
log.info("test2 {} - {}", num, i);
}
}
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test2(1);
});
executorService.execute(() -> {
example2.test2(2);
});
executorService.shutdown();
}
}
1.1 代碼塊修飾(對象)
此時,synchronized
用於保證test1
函數中的被synchronized
大括弧包裹的代碼同步執行.
synchronized
作用的對象為SynchronizedExample1
的對象實例,例如main
函數中的example1
以及example2
.
Tips:
1.example1
若在多個線程中被調用,其輸出順序將保證同步,按照1,2,3...19,20
的順序執行.
2.若example1
與example2
均在多個線程中執行,則test1...
之間保持同步輸出,test2...
之間保持同步輸出,但是test1...
與test2...
之間輸出不保證順序.
1.2 非靜態函數修飾
synchronized
添加於test2
函數聲明中,其作用類似於1.1
中的代碼塊修飾,區別點僅僅在於
其同步代碼塊擴充至整個函數
(test2
).
2. 類鎖
@Slf4j
public class SynchronizedExample2 {
private static final int loopNum = 20;
// 修飾一個類
private static void test1(int j) {
synchronized (SynchronizedExample2.class) {
for (int i = 0; i < loopNum; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修飾一個靜態方法
private static synchronized void test2(int j) {
for (int i = 0; i < loopNum; i++) {
log.info("test2 {} - {}", j, i);
}
}
public static void main(String[] args) {
SynchronizedExample2 example1 = new SynchronizedExample2();
SynchronizedExample2 example2 = new SynchronizedExample2();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test1(1);
});
executorService.execute(() -> {
example2.test1(2);
});
}
}
2.1 代碼塊修飾(類)
與1.1
中區別在於,synchronized
函數修飾的是SynchronizedExample2
類.
SynchronizedExample2
對象,諸如example1
或者example2
在任意多的線程中調用test1
函數,其輸出順序均會被保證(1,2,3,4...19,20
).
2.2 靜態函數修飾
功能與2.1
類似,均是對對象加鎖,確保多個類對象調用函數時保持順序.
Tips:
示例中,因為類上加鎖的原因,test1
與test2
對象保持順序執行,不會出現test1...
與test2...
交叉出現的現象.
3 synchronized
不能被繼承
需要註意,若synchronized
修飾於函數中,如1.2
以及2.2
,若有類繼承於SynchronizedExample1
或者SynchronizedExample1
,子類對象調用test2
不同步.
原因:synchronized
非函數簽名,因此無法被繼承,所以無法保證子類調用同步.
PS:
如果您覺得我的文章對您有幫助,可以掃碼領取下紅包,謝謝!