概念
在并發(fā)編程開發(fā)過程中,如果多個(gè)線程共享一塊資源,就會(huì)產(chǎn)生競爭條件,考慮安全性,需要同步機(jī)制保證代碼能夠正確執(zhí)行,保證任何時(shí)刻,只能有一個(gè)線程占有鎖和執(zhí)行同步代碼塊,沒有獲取到鎖的線程存放在等待隊(duì)列中。
實(shí)現(xiàn)方式
- synchronized關(guān)鍵字修飾需要同步的方法和對(duì)象
- Lock鎖機(jī)制實(shí)現(xiàn)同步
- 原子變量實(shí)現(xiàn)同步
synchronized
可以作為修飾符,也可以作為語句,即可以同步代碼塊,也可以同步方法。但獲得的都是對(duì)象鎖,每個(gè)對(duì)象只能有一個(gè)鎖。
案例
//共享對(duì)象
public class Synch {
int count = 0;
public void increse() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(1000);
count++;
System.out.println(count);
}
}
//調(diào)用
public class SynchDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Synch synch = new Synch();
for(int i=0;i<10;i++){
executorService.execute(()->{
try {
synch.increse();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
}
}
Synch類沒有加synchronized修飾時(shí),返回的結(jié)果為

A6E2E747-DD8D-4F44-B594-560D3CD365DC.png
Synch類加synchronized修飾時(shí),返回的結(jié)果為

5A443BCB-67CF-434D-8E2C-1809E22D4B04.png
public class LockSynch {
private AtomicInteger increase = new AtomicInteger(0);
private ReentrantLock lock = new ReentrantLock();
public void increase() {
try {
//lock.lock();
Thread.sleep(1000);
int number = increase.incrementAndGet();
System.out.println(number);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//lock.unlock();
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
LockSynch lockSynch = new LockSynch();
for(int i=0;i<10;i++){
executorService.execute(new Runnable(){
@Override
public void run() {
lockSynch.increase();
}
});
}
}
}
注:通過原子變量保證線程同步,但不保證線程的執(zhí)行順序。