亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

同步方法和對象鎖

同步方法和對象鎖

桃花長相依 2022-06-04 15:34:23
根據我的閱讀和理解,每個對象都有在嘗試訪問同步方法時發生的鎖定。這是我的代碼(在 2 個不同的類文件中):public class test { public synchronized void inc1( String who ) {         for( int i = 0 ; i < 1500 ; i++ )             System.out.println( who+": "+i ); }}public class testsyn implements Runnable {    test k = new test( );    public static void main( String[ ] args )    {        new Thread( new testsyn( ) ).start( );        new testsyn( ).doStuff( );    }    public void doStuff( ) { k.inc1( "Main" ); }    public void run( )    {        k.inc1( "Thread" );    }}所以假設我的輸出的第一行是:“Main:0”。這意味著主線程已經獲取了名為“k”的測試對象的密鑰,對吧?我創建的另一個線程怎么可能在主線程完成之前進入“inc1”方法并打印輸出?我注意到這個問題發生在這個特定的模式中,但是如果我將'k'設為靜態并改為寫這個(在testyn類中):public class testsyn implements Runnable {    static test k = new test( );    public static void main( String[ ] args )    {        new Thread( new testsyn( ) ).start( );        k.inc1( "Main" );    }    public void run( )    {        k.inc1( "Thread" );    }}這將按我預期的方式工作,并且輸出之間不會發生沖突。例如,如果主線程首先進入同步方法,那么其他線程將不得不等到主線程完成該方法。我在這里要問的問題是這種變化如何影響程序的行為?為什么?
查看完整描述

2 回答

?
江戶川亂折騰

TA貢獻1851條經驗 獲得超5個贊

所以假設我的輸出的第一行是:“Main:0”。這意味著主線程已經獲取了名為“k”的測試對象的密鑰,對吧?我創建的另一個線程怎么可能在主線程完成之前進入“inc1”方法并打印輸出?

你寫“名為'k'的測試對象”就好像只有一個一樣。在您的示例中,k是 class 的實例變量testsyn,因此每個實例都有自己的。它們指的是不同的對象,每個對象都有自己的監視器。因此,執行其中一個對象的同步實例方法的線程不會阻止另一個線程執行另一個對象的同步實例方法。

如果我將'k'設為靜態[...],輸出之間就不會發生沖突。

是的。 static變量屬于聲明它們的類。它們由所有實例共享。兩個線程共享一個 static k,在運行之前已經初始化main()并且之后沒有被修改。由于他們都試圖運行同一個對象的同步方法,因此必須等到另一個完成。


查看完整回答
反對 回復 2022-06-04
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

是的,synchronized關鍵字是用來獲取鎖的;鎖與對象實例相關聯。你有兩個test類的實例;一個給每個線程。所以沒有爭議。當字段k為靜態時,線程之間共享一個實例。



查看完整回答
反對 回復 2022-06-04
  • 2 回答
  • 0 關注
  • 91 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號