色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

不要重新分配被鎖定對象的對象引用

瀏覽:22日期:2024-07-20 17:21:59
內(nèi)容: synchronized 關(guān)鍵字鎖定對象。對象是在 synchronized 代碼內(nèi)部被鎖定的,這一點對此對象以及您對其對象引用所作的更改意味著什么呢?對一個對象作同步處理只鎖定該對象。但是,必須注意不要重新分配被鎖定對象的對象引用。那么如果這樣做會發(fā)生什么情況呢?請考慮下面這段代碼,它實現(xiàn)了一個 Stack:class Stack{private int StackSize = 10;private int[] intArr = new int[stackSize];private int index; //Stack 中的下一個可用位置。public void push(int val){synchronized(intArr) {//如果已滿,則重新分配整數(shù)數(shù)組(即我們的 Stack)。if (index == intArr.length){stackSize *= 2;int[] newintArr == new int[stackSize];System.arraycopy(intArr, 0, newintArr, 0, intArr.length);intArr = newintArr;}intArr[index] == val;index++;}}public int pop(){int retval;synchronized(intArr) {if (index> 0){retval = intArr[index-1]; //檢索值,index--; //并使 Stack 減少 1 個值。return retval;}}throw new EmptyStackException();}//...}這段代碼用數(shù)組實現(xiàn)了一個 Stack。創(chuàng)建了一個初始大小為 10 的數(shù)組來容納整數(shù)值。此類實現(xiàn)了 push 和 pop 方法來模擬 Stack 的使用。在 push 方法中,如果數(shù)組中沒有更多的空間來容納壓入的值,則數(shù)組被重新分配以創(chuàng)建更多的存儲空間。(故意沒有用 Vector 來實現(xiàn)這個類。Vector 中不能儲存基本類型。)請注意,這段代碼是要由多個線程進行訪問的。push 和 pop 方法每次對該類的共享實例數(shù)據(jù)的訪問都是在 synchronized 塊內(nèi)完成的。這樣就保證了多個線程不能并發(fā)訪問此數(shù)組而生成不正確的結(jié)果。這段代碼有一個主要的缺點。它對整數(shù)數(shù)組對象作了同步處理,而這個數(shù)組被 Stack 類的 intArr 所引用。當 push 方法重新分配此整數(shù)數(shù)組時,這個缺點就會顯露出來。當這種情況發(fā)生時,對象引用 intArr 被重新指定為引用一個新的、更大的整數(shù)數(shù)組對象。請注意,這是在 push 方法的 synchronized 塊執(zhí)行期間發(fā)生的。此塊針對 intArr 變量引用的對象進行了同步處理。因此,在這段代碼內(nèi)鎖定的對象不再被使用。請考慮以下的事件序列:線程 1 調(diào)用 push 方法并獲得 intArr 對象的鎖。線程 1 被線程 2 搶先。線程 2 調(diào)用 pop 方法。此方法因試圖獲取當前線程 1 在 push 方法中持有的同一個鎖而阻塞。線程 1 重新獲得控制并重新分配數(shù)組。intArr 變量現(xiàn)在引用一個不同的變量。push 方法退出并釋放它對原來的 intArr 對象的鎖。線程 1 再次調(diào)用 push 方法并獲得新 intArr 對象的鎖。線程 1 被線程 2 搶先。線程 2 獲得舊 intArr 對象的對象鎖并試圖訪問其內(nèi)存。現(xiàn)在線程 1 持有由 intArr 引用的新對象的鎖,線程 2 持有由 intArr 引用的舊對象的鎖。因為兩個線程持有不同的鎖,所以它們可以并發(fā)執(zhí)行 synchronized push 和 pop 方法,從而導致錯誤。很明顯,這不是所希望的結(jié)果。這個問題是因 push 方法重新分配被鎖定對象的對象引用而造成的。當某個對象被鎖定時,其他線程可能在同一個對象鎖上被阻塞。如果將被鎖定對象的對象引用重新分配給另一個對象,其他線程的掛起鎖則是針對代碼中已不再相關(guān)的對象的。您可以這樣修正這段代碼,去掉對 intArr 變量的同步,而對 push 和 pop 方法進行同步。通過將 synchronized 關(guān)鍵字添加為方法修飾符即可實現(xiàn)這一點。正確的代碼如下所示:class Stack{//與前面相同...public synchronized void push(int val){//如果為空,則重新分配整數(shù)數(shù)組(即我們的 Stack)。if (index == intArr.length){stackSize *= 2;int[] newintArr = new int[stackSize];System.arraycopy(intArr, 0, newintArr, 0, intArr.length);intArr = newintArr;}intArr[index]= val;index++;}public synchronized int pop(){int retval;if (index> 0){retval = intArr[index-1];index--;return retval;}throw new EmptyStackException();}}這個修改更改了實際上獲取的鎖。獲取的鎖是針對為其調(diào)用方法的對象的,而不是鎖定 intArr 變量所引用的對象。因為獲取的鎖不再針對 intArr 所引用的對象,所以允許代碼重新指定 intArr 對象引用。作者簡介 Peter Haggar 是 IBM 的高級軟件工程師。他目前正在研究新興的 Java 和因特網(wǎng)技術(shù),并且是 IBM 實時 Java 參考實現(xiàn)的項目主持人。他有豐富的編程經(jīng)驗,從事過開發(fā)工具、類庫和操作系統(tǒng)等方面的工作。在許多行業(yè)研討會上,他也經(jīng)常就 Java 和其他技術(shù)作技術(shù)性發(fā)言。他于 1987 年在紐約獲得 Clarkson 大學計算機科學學士學位??梢酝ㄟ^ [email protected] 與他聯(lián)系。出處 IBM DW Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
相關(guān)文章:
主站蜘蛛池模板: 九九精品99久久久香蕉 | 506rr亚洲欧美 | 91精品国产91热久久久久福利 | 日本巨乳中文字幕 | 久草视频福利 | 亚洲在线视频免费观看 | 日本综合欧美一区二区三区 | 国产成人资源 | 欧美做爰孕妇群 | 久草视频网 | 久久精品欧美日韩精品 | 亚洲一片 | 欧美一级亚洲一级 | 99秒拍福利大尺度视频 | 久久一级视频 | 亚洲一区 欧美 | 中文字幕一区二区三区 精品 | 久久精品免费视频观看 | 成人怡红院视频在线观看 | 国产成人精品aaaa视频一区 | 一级黄色录像片 | 久久久这里只有精品免费 | vr18成人资源 | 欧美在线看欧美高清视频免费 | 国产在线一区在线视频 | 欧美在线三级 | 久草热线视频 | 亚洲国内精品 | 97在线视频免费播放 | 亚洲精品人成在线观看 | 亚洲欧美视频一区二区 | 人成免费a级毛片 | 在线精品免费观看综合 | 成年人性网站 | 成人免费大片a毛片 | 国产日韩欧美一区二区 | 免费刺激视频 | 欧美一级片在线免费观看 | 国产精品久久久久久久久岛 | 真正免费一级毛片在线播放 | 久久 在线|