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

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

疑惑System.out.println對輸出結果的影響,請問該怎么解決?

疑惑System.out.println對輸出結果的影響,請問該怎么解決?

胡說叔叔 2022-05-19 12:15:25
首先,看如下代碼,是一個同步方法鎖的例子:package sync;public class TT implements Runnable{int b=100;//第三處 int c=100;public synchronized void m1(){//(第一處)System.out.println(Thread.currentThread().getName());b=1000;System.out.println(Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("b="+b);}public synchronized void m2(){//(第二處)System.out.println(Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}b=2000;}public void run(){m1();}public static void main(String[] args) {TT tt=new TT();Thread t=new Thread(tt);t.start();tt.m2();//第四處:System.out.println(tt.c);System.out.println(tt.b);//第五處:System.out.println(tt.c);}m1和m2 方法都用了synchronized同步。我是這樣理解的,但不知道是否正確:當主線程main調用tt.m2()方法,獲得了方法鎖,并且鎖住了變量b。線程t無法繼續執行m1()方法,因為m1()要對變量b進行操作,只有等m2方法執行完畢后,才能執行。System.out.println(tt.b);帶來的結果是b=1000;以上程序執行后的結果如下:1000Thread-0b=1000那么問題來了!情況1:當在程序第一處或者程序第二處位置添加語句:System.out.println(Thread.currentThread().getName());都會造成輸出結果的改變,System.out.println(tt.b);帶來的結果是b=2000;情況2:在源程序基礎上,在第二處添加語句:System.out.println(Thread.currentThread().getName());原本最后System.out.println(tt.b);帶來的結果是b=2000。但是,如果繼續在//第三處添加int c=100;并且在//第四處添加System.out.println(tt.c);那么運行后,System.out.println(tt.b);帶來的結果又變為b=1000;如果,把//第四處System.out.println(tt.c);放在//第五處的位置上System.out.println(tt.b);帶來的結果又變為b=2000;m1和m2方法中的sleep方法中的值,也對組后的輸出結果有影響。在測試時,偶然發生過,但并不規律。求指點。
查看完整描述

2 回答

?
人到中年有點甜

TA貢獻1895條經驗 獲得超7個贊

java虛擬機對于線程的調度是無法直接操控的,只要有線程,具體執行那個線程也是無法預知的,你的這個情況很大一部分是巧合與運氣
唯一的解釋是System.out.println(Thread.currentThread().getName());是一個耗時操作與sleep方法拖延的時間不相上下,你的sync關鍵字甚至沒起到作用
你把b=2000改成b+=2000;
然后試試加sync與不加,如果不加,執行t.start();tt.m2();后b有可能等于1100 2100 或者3100雖然可能性不大,因為這個小程序線程切換的幾率不大
加了sync就能保證100加1000再加2000后是3100,而不是其他的過期數據,這才是sync作用

查看完整回答
反對 回復 2022-05-23
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

你的synchronized加在線程的代碼里,你要鎖應該要把代碼放到主線程中
這樣,你每new一個Thread,它都持有這個synchronized 的m1方法,并沒有其它線程去調用
線程都是調用自己的synchronized 方法,不知道你明白了沒有
如果你想加鎖,應該把synchronized 寫到外部去,或者加上static

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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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