日期:2014-05-20  浏览次数:20669 次

关于线程锁定的问题,纠结了一晚上
public class TTT implements Runnable {
int b = 100;

public static void main(String[] args) throws InterruptedException {
TTT tt = new TTT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
}

private synchronized void m2() throws InterruptedException {
System.out.println("m2=" + b);
b = 2000;
}

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

public synchronized void m1() throws InterruptedException {
System.out.println("开始的b=:" + b);
b = 1000;
Thread.sleep(5000);
System.out.println("m1=" + b);
}
}

我睡眠了5秒 前面的b=2000为什么改变不了m1的值

------解决方案--------------------
首先要进入m1要所有锁tt,进入m2也要持有锁tt


t.start();可能立马就进入了run,进入了m1

也有可能调用了start后线程切换执行了主线程的tt.m2

换而言之,此例中,m1和m2谁先执行是不确定的,与CPU的快慢,JVM的实现等等都有关系
------解决方案--------------------
你代码的结果是:
m2=100
2000
开始的b=:2000
m1=1000
这个要看main线程和t.start()这个线程谁先强到锁执行 这个结果是main线程先抢到的 因而先执行m2,并且锁住该线程此时b=100(输出m2=100)然后b=2000(输出2000),该锁结束了 然后t.start()执行m1 (输出开始的b=:2000)然后b=1000(输出m1=1000)

这个程序主要是看谁先强到了该锁............

------解决方案--------------------
(我机器上tt.m2(),即主线程先执行)

主线程没有Sleep,结束的比较快,
System.out.println(tt.b);//输出1000,子线程还在运行

如果加上 t.join(); //主线程等待子线程结束。
System.out.println(tt.b);//输出2000,