线程-synchronized(this)的含义和wait和sleep的区别

来源:互联网 发布:做图软件 编辑:程序博客网 时间:2024/06/03 18:30
1、synchronized(this)的含义,是锁定当前对象,还是锁定一段代码,举个例子看看能另外一个线程能否访问这个类对private属性。 事实证明,synchronized修饰的method1的话,如果该类中method2没有加synchronized修饰符,则如果在执行 method1的过程中,主线程可以执行了method2,也就是说,如果method2改变该类属性的话,在method1得到的属性是改变后的属性。读脏数据。不一致性。如何解决,那就是method2前面也加synchronized修饰符。该修饰符表示获得这个对象的锁,一个对象只有一个锁,如果你想获得他的锁的话,你必须等我执行完成。所以如果一个类中有个synchronized方法,那么你要看看别的方法是否用到该方法中的属性,如果是则也要加synchronized。

注意在JVM中,有个计数器的,如果调用了某个带synchronized的方法,计数器+1,一开始是0,如果在执行该方法时候又调用了其他synchronized方法,那么计数器再+1,方法执行结束返回,计数器-1,知道计数器为0,表示这个对象的锁被释放了。
熟读线程中的TT.java搞清synchronized

TT.java

public class TT implements Runnable {
int b = 100;

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

public synchronized void m2() throws Exception {
System.out.println("测试方法2:"+b);
   Thread.sleep(2500);
   b = 2000;
System.out.println("b= "+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();
   //哈哈通过下面的循环主线程执行的m2被我搞到比t线程慢了
   for(int i=0;i<100000;i++){
    c+=i;
   }
   /*
   try{
    Thread.sleep(1000);//先让m1先执行输出b =1000,如果没加这句sleep则先执行m2,输出2000
    //然后在执行m1,输出 b=1000
   }catch(Exception e){}   */
   tt.m2();//再执行m2执行输出2000
   try{
    Thread.sleep(1000);//先输出1000,再输出 b=1000;记住主线程比子线程速度快就对了,相同行数
    //也许主线程会优先
   }catch(Exception e){}
   System.out.println("这是2:"+tt.b);
   System.out.println(c);
}
}
//你这样做,首先打印出测试b =100,过7秒钟,b=1000,然后把锁交给tt.m2,m2先打印出测试方法2:1000,等待2.5秒,后输出b=2000,最后输出这是2:2000
//一个对象一个锁
//猜测:主线程快,线程1:所以tt.m2()比m1()先调用,所以先执行m2方法,执行m2方法要2.5秒,然后执行m1方法,执行m1方法要5秒钟,
//主线程,过了2.5秒后,m2方法执行结束,过了1秒后,打印出tt.b的值。
//所以打印出的值是这样的,过了2.5秒后,首先打印出b=2000,接着就是测试b = 2000,然后过了1秒后,打印出2000,(这里为什么是1000,因为太快乐,线程1:b=1000)然后过5秒,打印出b=1000;

2、wait和sleep方法的区别,前面是object的,sleep是Thread类的,wait释放当前对象的锁,sleep不会释放。每个对象都有且只有一个锁,如果对象的类有多个synchronized方法,则先执行的方法首先获得该锁,而其他方法要等该方法执行完成才能获得该锁后才能执行,而获得该锁的方法还可调用其他synchronized方法,而此时jvm会跟踪加锁次数,刚刚是1,调用一个+1,直到全部执行完成为0时才自动释放。
0 0
原创粉丝点击