java中synchronized用法+自己的一个小结~!

java中synchronized用法           

源地址:http://blog.csdn.net/chenguang79/article/details/677720

作者:                             chenguang79

      之前一直困惑于   synchronized(){}  语句块的问题  。()内到底是传什么?synchronized锁什么?   看了这篇文章,也有了一点清晰吧!单直到看到这篇文章的以下评论,问题就来了!!!


我自己也去试了下,可以得到的结果就是  此时是同步了的。但我上面的两个问题又晕了 

所以我纠结呀。就又有了以下小结吧!!

synchronized(){}  语句块中  

1.()传的是你要锁的对象也可以,类模板也行!

2.但最终比较的是:如果是传对象就得两个对象相同时锁,或者传类模板(类模板必须是类名.class   才会判别成功    如果的对象.getClass()  就还是会判别为该对象而不是类模板)则是该类全部都

例:代码1   时没有锁住  即  obj  obj.getClass新对象 新对象.getClass()  都不能锁住

代码1:

public class NewTest {
             private static int num=0;//用于判断是否锁住之一

             public static void Learing(Object obj,String a){
                    synchronized (obj.getClass()) {
                         System.out.println(obj.getClass());
                            num++;
                           System.out.println(a+":开始上课"+num);
                      }
              }

            public static void main(String[] args) {
                  Theacher t=new Theacher();
                  Students s=new Students();
                    t.start();
                  s.start();
             }
}

class Students extends Thread {
 public void run() {
  NewTest.Learing(this,"学生");
 }
}
class Theacher extends Thread {
 public void run() {
  NewTest.Learing(this,"老师");
 }
}

锁住的情况:即为 Object.class   Students(Teacher).class  

还有一种对象实例方法直接传 “ this ” 肯定能锁就没又试了。


直到我准备上传时,又一个问题来了!以上代码中传入NewTest.class    new NewTest().getClass()  时会锁住!!!  new NewTest()时不会锁住!!!

代码2:

public class NewTest {
 public static void main(String[] args) {
  Theacher t=new Theacher();
  Theacher t0=new Theacher();
  Students s=new Students();
  t.start();
  t0.start();
  s.start();
 }
}
class NewTest1{
 private static int num=0;
 public static void Learing(Object obj,String a){
  synchronized (new NewTest().getClass()) {
   System.out.println(obj.getClass());
    num++;
   System.out.println(a+":开始上课"+num);
  }
 }
}

换成这个代码也是一样的。按道理应该都不会锁住的呀!!


3.将synchronized作用于static函数,示例代码如下:

示例:

      Class Foo

{

public synchronized static void methodAAA()   //同步的static函数

{

//….

}

public void methodBBB()

{

       synchronized(Foo.class)   //  class literal(类名称字面常量)

}

       }

   代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。


这是源文章,我还是之前没读懂呀!意思两个方法是同一个效果,静态方法默认会锁该方法所在类的 类模板 。

最后得出:

 * 静态synchronized (){}中貌似可以放任何 在内存中有地址的数据(对象,
 * 类模版,数组,枚举
都可以)  但不能为空
 * 而且都是启动了 同步锁 语句块,问题是是否是同一个同步锁。
 * ()内传入了一个已经存在的内存地址并且不会改变时,就会把该语句块看作
 * 时同一把锁,这也说明如果是新创建了一个对象(new关键字时)时 ,产生了两
 * 个新对象,新地址,不会达到同步锁的效果,所以新对象.getClass()也是一样的,
 * 新创了两个对象,地址不同了,虽然类模版是同一个。
 * 如果在语句块中改变了()内的数据,这个锁可能就不会达到效果,也就反面验证以上结论!
 * 类似于synchronized是一个门,()是一个门卫,一个线程进去后如果门卫就换了,
 * 新门卫肯定不认识后面的线程,就会让它进去!(之前理解错了,以为是类似对象比较)
 * 而非静态synchronized (){}中相较于以上就多一个this  当该语句块没结束
 * 时this一直不会改变,所以只要不是新对象调用就不会出现没同意锁的问题




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值