JAVA线程的问题

来源:百度知道 编辑:UC知道 时间:2024/05/13 16:22:14
public class TT implements Runnable {
int b = 100;

public synchronized void m1() throws Exception{
//Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}

public /*synchronized*/ void m2() //throws Exception
{
/*Thread.sleep(2500);
b = 2000;*/
System.out.println(b);
}

public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
Thread.sleep(1000);
tt.m2();
//System.out.println(tt.b);
}
}
为什么主线程调用m2()方法,输出的结果也是1000,而不是100?

关键不是synchronized ,而是main中第2行:Thread t = new Thread(tt);

Thread对象需要一个实现Runnable 接口的对象才能实例化,这个你也知道,OK,那么你还要知道的是,当Thread对象被实例化时,Thread对象其中就包含了那个构造函数中的对象,即tt

所以t中包含了tt,当tt中的b被改变时,从t来调用的b也自然也被改变了

你写的这个程序是用t影响了tt,反过来,用tt也可以影响t,不信你可以做如下改动:
把m1中的b = 1000;改为b -= 1000;
在主函数中的Thread t = new Thread(tt); 后添加语句:
tt.b = 10000;

然后再编译运行,就会看到,虽然是用tt访问了b,改变了值,但是事先就将tt包含在了t中间,所以后面的显示,无论是从t还是从tt访问b,其值都是一样的,因为在t中包含的那个含有整形b的对象,就是外面的这个tt

不知道这样说你明白了吗

因为m1用synchronized来锁定,只有执行完这个方法后才会进行接下来的操作,所以就会这个结果。