Java Synchronized鎖失敗案例及解決方案
synchronized關(guān)鍵字,一般稱之為”同步鎖“,用它來(lái)修飾需要同步的方法和需要同步代碼塊,默認(rèn)是當(dāng)前對(duì)象作為鎖的對(duì)象。
同步鎖鎖的是同一個(gè)對(duì)象,如果對(duì)象發(fā)生改變,則鎖會(huì)不生效。
鎖失敗的代碼:
public class IntegerSynTest {
//線程實(shí)現(xiàn)Runnable接口
private static class Worker implements Runnable{
private Integer num;
public Worker(Integer num){
this.num=num;
}
@Override
public void run() {
synchronized (num){
Thread thread = Thread.currentThread();
//System.identityHashCode:返回原生的hashCode值,不管Object對(duì)象是被重寫;空引用的哈希代碼為零
System.out.println(thread.getName()+"--@:---"+System.identityHashCode(num));
num++;
System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
}
}
public static void main(String[] args) {
Worker worker = new Worker(1);
for (int i = 0; i < 5; i++) {
new Thread(worker).start();
}
}
}
}
鎖失敗的運(yùn)行結(jié)果:

鎖失敗的原因:
1.num++ 的 .class 實(shí)現(xiàn)是這樣的 Integer integer1 = this.num, integer2 = this.num = Integer.valueOf(this.num.intValue() + 1);
2.查看 Integer.valueOf()的源代碼

這時(shí)發(fā)現(xiàn),它是重新 new出一個(gè)新的Integer,這樣的話,每 ++一次,那么就會(huì)產(chǎn)生一個(gè)新的對(duì)象,而Synchronize鎖是鎖同一個(gè)對(duì)象,當(dāng)鎖不同對(duì)象時(shí),則會(huì)鎖失敗。
解決方法:
Synchronized同步鎖只要鎖的對(duì)象不發(fā)生改變即可,那么由此只需要聲明一個(gè)對(duì)象,不修改它,鎖這一個(gè)對(duì)象即可(還有其他方法暫不一一列舉,以后也不會(huì)列舉了)。
鎖成功的代碼
public class IntegerSynTest {
//線程實(shí)現(xiàn)Runnable接口
private static class Worker implements Runnable{
private Integer num;
/**
* ---重點(diǎn)看這里---
* 聲明要鎖的對(duì)象
* ---重點(diǎn)看這里---
*/
private Object object = new Object();
public Worker(Integer num){
this.num=num;
}
@Override
public void run() {
//修改鎖對(duì)象
synchronized (num){
Thread thread = Thread.currentThread();
//System.identityHashCode:返回原生的hashCode值,不管Object對(duì)象是被重寫;空引用的哈希代碼為零
System.out.println(thread.getName()+"--@:---"+System.identityHashCode(num));
num++;
System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
}
}
public static void main(String[] args) {
Worker worker = new Worker(1);
for (int i = 0; i < 5; i++) {
new Thread(worker).start();
}
}
}
}
鎖成功的運(yùn)行結(jié)果:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中反射的"暴破"機(jī)制(SetAccessible方法)詳解
這篇文章主要為大家詳細(xì)介紹了Java中反射的"暴破"機(jī)制,以及如何利用這一機(jī)制實(shí)現(xiàn)訪問(wèn)非公有屬性,方法,和構(gòu)造器,文中示例代碼講解詳細(xì),感興趣的可以了解一下2022-08-08
關(guān)于maven項(xiàng)目引入maven庫(kù)沒(méi)有的jar處理辦法
這篇文章主要介紹了關(guān)于maven項(xiàng)目引入maven庫(kù)沒(méi)有的jar處理辦法,在平時(shí)開發(fā)中,有些jar包是不存在maven中央庫(kù)中的,那么此時(shí)該如何解決才能方便后續(xù)處理呢,需要的朋友可以參考下本文2023-03-03
SpringBoot集成ShardingSphere實(shí)現(xiàn)數(shù)據(jù)庫(kù)分表
ShardingSphere?是一個(gè)開源的分布式數(shù)據(jù)庫(kù)中間件,旨在為應(yīng)用提供數(shù)據(jù)庫(kù)分片、讀寫分離、分布式事務(wù)等功能,下面我們來(lái)看看SpringBoot如何集成ShardingSphere實(shí)現(xiàn)數(shù)據(jù)庫(kù)分表吧2024-12-12
Java8加java10等于Java18的版本查看及特性詳解
這篇文章主要為大家介紹了Java?8加java10等于Java18的各個(gè)版本要點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
springboot+jwt+springSecurity微信小程序授權(quán)登錄問(wèn)題
這篇文章主要介紹了springboot+jwt+springSecurity微信小程序授權(quán)登錄問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
在Mac下IDEA安裝并使用protobuf方式(Java)
這篇文章主要介紹了在Mac下IDEA安裝并使用protobuf方式(Java),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11

