猿问

疑惑System.out.println对输出结果的影响,请问该怎么解决?

首先,看如下代码,是一个同步方法锁的例子:
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;
以上程序执行后的结果如下:
1000
Thread-0
b=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方法中的值,也对组后的输出结果有影响。在测试时,偶然发生过,但并不规律。求指点。

胡说叔叔
浏览 213回答 2
2回答

人到中年有点甜

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作用

呼啦一阵风

你的synchronized加在线程的代码里,你要锁应该要把代码放到主线程中这样,你每new一个Thread,它都持有这个synchronized 的m1方法,并没有其它线程去调用线程都是调用自己的synchronized 方法,不知道你明白了没有如果你想加锁,应该把synchronized 写到外部去,或者加上static
随时随地看视频慕课网APP
我要回答