关于synchronized怎么理解,synchronized锁方法和锁代码块有什么区别?
有以下一个程序
public class TT extends Thread{
int b=100;
public synchronized void m1(){
b=1000;
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("b="+b);
}
public synchronized void m2(){
b=2000;
try{
Thread.sleep(2500);
}catch(Exception e){
e.printStackTrace();
}
}
public void run(){
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
TT tt = new TT();
tt.start();
tt.m2();
System.out.println(tt.b);
}
}
运行结果是:
2000
b=1000
如果把m2方法的synchronized关键字去掉的话运行结果就是:
1000
b=1000
为什么两次的结果不一致?
我想问的是这个程序中的synchronized方法到底锁的是什么东西?
要求强人对内存进行分析,希望不是三言两语就说完了。。
我自己的分析如下:
首先执行主线程的main方法,在栈空间一个变量tt指向堆空间的一个TT对象。主线程的main方法调用tt.start()方法,启动了一个tt线程,这个线程进入可运行状态,但是可能占有CPU,也可能没有占有CPU.然后住线程调用tt.m2方法,把TT对象锁住了,b的值从100变成2000,然后Thread.sleep(2500),这个时候住线程就进入到睡眠状态,但是因为加了synchronized,所以tt线程得不到TT对象,所以只有等待主线程睡2.5秒自己醒。再往下执行,这个时候就打印出了2000这个值,同时将锁释放掉,这个时候tt线程拿到了锁,得到b的值,这时候b的值是2000,tt线程调用m1()方法,将b的值改成1000,然后tt线程睡眠5秒钟,将b=1000打印出来。不知道我的理解有哪些是不合理的地方?
还有其中几点存在疑惑,1.tt.start()方法,是使一个线程进入可运行状态吗?但是这个线程还没有运行?还是说这个线程有可能获得CPU马上运行,还是在可运行池中等待运行呢?这个方法不是很理解。。。
2.如果是实例变量,那么方法锁会把这个实例变量锁住吗,其他线程暂时就不能访问这个实力变量?我读synchronized方法就是这样理解的,不知道这样是不是正确的。。
哪位高手帮我解答下啊,我被多线程搞糊涂了。。。感觉书上有时候也讲得不详细!!!