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í)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. JSP之表單提交get和post的區(qū)別詳解及實(shí)例2. CSS可以做的幾個(gè)令你嘆為觀止的實(shí)例分享3. Xml簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理4. jsp+servlet實(shí)現(xiàn)猜數(shù)字游戲5. javascript xml xsl取值及數(shù)據(jù)修改第1/2頁(yè)6. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案7. jsp文件下載功能實(shí)現(xiàn)代碼8. 將properties文件的配置設(shè)置為整個(gè)Web應(yīng)用的全局變量實(shí)現(xiàn)方法9. ASP常用日期格式化函數(shù) FormatDate()10. JSP+Servlet實(shí)現(xiàn)文件上傳到服務(wù)器功能
