Java Synchronized鎖失敗案例及解決方案
synchronized關鍵字,一般稱之為”同步鎖“,用它來修飾需要同步的方法和需要同步代碼塊,默認是當前對象作為鎖的對象。
同步鎖鎖的是同一個對象,如果對象發(fā)生改變,則鎖會不生效。
鎖失敗的代碼:
public class IntegerSynTest { //線程實現(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對象是被重寫;空引用的哈希代碼為零 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(); } } } }
鎖失敗的運行結果:
鎖失敗的原因:
1.num++ 的 .class 實現(xiàn)是這樣的 Integer integer1 = this.num, integer2 = this.num = Integer.valueOf(this.num.intValue() + 1);
2.查看 Integer.valueOf()的源代碼
這時發(fā)現(xiàn),它是重新 new出一個新的Integer,這樣的話,每 ++一次,那么就會產生一個新的對象,而Synchronize鎖是鎖同一個對象,當鎖不同對象時,則會鎖失敗。
解決方法:
Synchronized同步鎖只要鎖的對象不發(fā)生改變即可,那么由此只需要聲明一個對象,不修改它,鎖這一個對象即可(還有其他方法暫不一一列舉,以后也不會列舉了)。
鎖成功的代碼
public class IntegerSynTest { //線程實現(xiàn)Runnable接口 private static class Worker implements Runnable{ private Integer num; /** * ---重點看這里--- * 聲明要鎖的對象 * ---重點看這里--- */ private Object object = new Object(); public Worker(Integer num){ this.num=num; } @Override public void run() { //修改鎖對象 synchronized (num){ Thread thread = Thread.currentThread(); //System.identityHashCode:返回原生的hashCode值,不管Object對象是被重寫;空引用的哈希代碼為零 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(); } } } }
鎖成功的運行結果:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java數(shù)據(jù)結構貪心算法的實現(xiàn)
本文主要介紹了Java數(shù)據(jù)結構貪心算法的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2007-03-03繼承WebMvcConfigurationSupport后自動配置不生效及如何配置攔截器
這篇文章主要介紹了繼承WebMvcConfigurationSupport后自動配置不生效及如何配置攔截器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11