亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

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

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

瀏覽:42日期: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 中不能儲存基本類型。)請注意,這段代碼是要由多個線程進(jìn)行訪問的。push 和 pop 方法每次對該類的共享實例數(shù)據(jù)的訪問都是在 synchronized 塊內(nèi)完成的。這樣就保證了多個線程不能并發(fā)訪問此數(shù)組而生成不正確的結(jié)果。這段代碼有一個主要的缺點。它對整數(shù)數(shù)組對象作了同步處理,而這個數(shù)組被 Stack 類的 intArr 所引用。當(dāng) push 方法重新分配此整數(shù)數(shù)組時,這個缺點就會顯露出來。當(dāng)這種情況發(fā)生時,對象引用 intArr 被重新指定為引用一個新的、更大的整數(shù)數(shù)組對象。請注意,這是在 push 方法的 synchronized 塊執(zhí)行期間發(fā)生的。此塊針對 intArr 變量引用的對象進(jìn)行了同步處理。因此,在這段代碼內(nèi)鎖定的對象不再被使用。請考慮以下的事件序列:線程 1 調(diào)用 push 方法并獲得 intArr 對象的鎖。線程 1 被線程 2 搶先。線程 2 調(diào)用 pop 方法。此方法因試圖獲取當(dāng)前線程 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 方法,從而導(dǎo)致錯誤。很明顯,這不是所希望的結(jié)果。這個問題是因 push 方法重新分配被鎖定對象的對象引用而造成的。當(dāng)某個對象被鎖定時,其他線程可能在同一個對象鎖上被阻塞。如果將被鎖定對象的對象引用重新分配給另一個對象,其他線程的掛起鎖則是針對代碼中已不再相關(guān)的對象的。您可以這樣修正這段代碼,去掉對 intArr 變量的同步,而對 push 和 pop 方法進(jìn)行同步。通過將 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 大學(xué)計算機科學(xué)學(xué)士學(xué)位。可以通過 haggar@us.ibm.com 與他聯(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)文章:
主站蜘蛛池模板: 久草一区 | 在线看国产 | 欧美一区中文字幕 | 黄色一级性生活视频 | 国产精品酒店 | 日韩欧美亚洲综合一区二区 | 国产九九在线视频 | 一本色道久久综合亚洲精品加 | 蕾丝视频在线观看www | 国产色婷婷 | 免费精品久久久视频 | 国产精品成人影院 | 国内成人免费视频 | 毛片应用 | 国产一区二区三区四区在线 | 国产女主播真实视频在线观看 | 亚洲精品日韩在线一区 | 伊人伊成久久人综合网777 | 欧美激情大尺度做爰叫床声 | 黄色一级视频免费 | 最新欧美精品一区二区三区不卡 | 国产成人免费全部网站 | 久久综合图片 | 日韩黄色中文字幕 | 欧美第一页草草影院 | 亚洲国产高清在线精品一区 | 美女黄色一级毛片 | 美美女高清毛片视频黄的一免费 | 在线播放交视频 | 91黑丝国产线观看免费 | 日韩一二区| 国产精品亚洲欧美日韩一区在线 | 亚洲欧美中日韩中文字幕 | 好色婷婷| 91天堂97年嫩模在线观看 | pans国产大尺度私密拍摄视频 | 中国一级特黄毛片 | 久久国产免费观看 | 欧美α一级毛片 | 91香蕉视频免费在线观看 | 亚洲毛片在线免费观看 |