通過實(shí)例解析synchronized和lock區(qū)別
1,原始構(gòu)成
synchronized是關(guān)鍵字,屬于JVM層面,通過wait,notify和notifyAll來調(diào)度線程。
Lock是具體類,是api層面的鎖。
2,使用方法
synchronized不需要用戶手動去釋放鎖, 當(dāng)synchronized代碼執(zhí)行完后,系統(tǒng)會自動釋放鎖。
Lock需要用戶手動釋放鎖,否則會出現(xiàn)死鎖現(xiàn)象。需要lock和unlock配合try/finally語句塊來完成。
3,等待是否中斷
synchronized不可中斷,除非拋出異?;蛘哒_\(yùn)行完畢。
Lock可中斷,可以設(shè)置超時(shí)方法或者調(diào)用中斷方法。
4,加鎖是否公平
synchronized非公平鎖。
Lock默認(rèn)非公平鎖,可指定為公平鎖。
5,鎖綁定多個(gè)條件condition
synchronized沒有。
Lock用來分組喚醒需要喚醒的線程,可以精確喚醒,而不是像synchronized一樣要么隨機(jī)喚醒一個(gè)線程,要么全部喚醒。
Demo: 練習(xí)
多線程之間按順序調(diào)用,實(shí)現(xiàn)A->B->C三個(gè)線程啟動,要求:AA打印5次,BB打印10次,CC打印15次,重復(fù)10遍。
package com.demo.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareResource{
int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(){
lock.lock();
try {
while(number!=1){
c1.await();
}
for(int i=1;i<=5;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 2;
c2.signal();
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void print10(){
lock.lock();
try {
while(number!=2){
c2.await();
}
for(int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 3;
c3.signal();
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void print15(){
lock.lock();
try {
while(number!=3){
c3.await();
}
for(int i=1;i<=15;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 1;
c1.signal();
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
public class TestReentrantLock {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for(int i=1;i<=10;i++){
shareResource.print5();
}
},"AA").start();
new Thread(()->{
for(int i=1;i<=10;i++){
shareResource.print10();
}
},"BB").start();
new Thread(()->{
for(int i=1;i<=10;i++){
shareResource.print15();
}
},"CC").start();
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 深入Synchronized和java.util.concurrent.locks.Lock的區(qū)別詳解
- 詳談Lock與synchronized 的區(qū)別
- Java編程synchronized與lock的區(qū)別【推薦】
- 簡單了解synchronized和lock的區(qū)別
- 淺談Synchronized和Lock的區(qū)別
- Java 多線程Synchronized和Lock的區(qū)別
- 淺談Java中Lock和Synchronized的區(qū)別
- Java常用鎖synchronized和ReentrantLock的區(qū)別
- synchronized?和?Lock?的異同點(diǎn)(如何讓選擇)
相關(guān)文章
圖解Java?ReentrantLock的條件變量Condition機(jī)制
想必大家都使用過wait()和notify()這兩個(gè)方法把,他們主要用于多線程間的協(xié)同處理。而RenentrantLock也支持這樣條件變量的能力,而且相對于synchronized?更加強(qiáng)大,能夠支持多個(gè)條件變量,本文就來詳細(xì)說說2022-10-10
Java實(shí)現(xiàn)數(shù)據(jù)庫連接的最詳細(xì)教程分享
JDBC,Java?Database?Connectivity,即Java數(shù)據(jù)庫連接,是?Java?中的一套和數(shù)據(jù)庫進(jìn)行交互的API,本文就來講講Java如何利用JDBC實(shí)現(xiàn)數(shù)據(jù)庫的連接吧2023-05-05
java環(huán)境變量為什么要配置path和classpath詳細(xì)解答
為何配置path?為何配置classpath?當(dāng)時(shí)初學(xué)java時(shí)只是關(guān)心如何做而不去關(guān)心這些問題,接下來介紹一下,感興趣的朋友可以參考下哦2013-01-01
解讀@ConfigurationProperties的基本用法
這篇文章主要介紹了@ConfigurationProperties的基本用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
RabbitMQ,RocketMQ,Kafka?事務(wù)性,消息丟失,消息順序性和消息重復(fù)發(fā)送的處理策略問題
這篇文章主要介紹了RabbitMQ,RocketMQ,Kafka?事務(wù)性,消息丟失,消息順序性和消息重復(fù)發(fā)送的處理策略,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03

