好久没写博文了,忙碌了一年多,在技术上走了好多弯路,还好由于自己坚持不懈的努力终于从弯路中摆脱出来了,最近想回顾下关于java线程同步的知识,在这里抛砖引玉,希望热爱技术的程序猿们能一起进步。

   说到java线程同步肯定离不开synchronized,而关于synchronized这个关键字的细节,热爱技术的朋友们是否真正掌握了呢?

   大家都知道,每个java类都有一个继承来自Object的对象锁,也就是说new一个实例的同时虚拟机就赋予了这个实例的一个对象锁,并且这个锁是唯一的,那么这个跟synchronized这个有什么关系呢?关系大着呢,看以下代码:

class Demo1 {
   int index = 0;
   public synchronized void getI() {
       index=index+1;
   }
   public synchronized void setI() {
       index=index-1;
   }

}

class Demo2 {
   int index = 0;
   public synchronized void getI() {
       index=index+1;
   }
   public void setI() {
       index=index-1;
   }

}

Demo1类里面有两个声明了synchronized这个关键字的方法,Demo2里面只有一个方法加了声明,这两者的区别是什么呢?(这里有兴趣的朋友可以自己写测试用例去观察一下index变量的区别,这里只把结论说出来)。如果你真正测试了,你就会发现Demo1的某个实例中在多线程环境下的某个时刻只能执行一个方法,而Demo2可以同时执行,为什么呢?这里面就有上面说到的对象锁的概念了,一个synchronized关键字表明该对象锁正在被占用,一个声明了synchronized关键字的方法只有拿到当前对象的对象锁才能执行该方法。

   以上只是单纯的谈了同步方法没有谈同步代码块,其实两者的区别主要就是作用域大小的关系,在这里就不多坐解释了。

   大家一定还想知道synchronized static与synchronized两者的区别吧,大家可能都知道static是类级别的关键字,已经超越了对象的概念了,那么简单点大家可以理解为类锁,没错JDK有对象锁的概念也有类锁的概念呢。

class Demo {
   int index = 0;

   public synchronized static void getI(Demo demo) {
       demo.index=demo.index+1;
   }

   public synchronized void getI() {
       index=index+1;
   }

   public synchronized  void setI() {
       index=index-1;
   }
   public synchronized static void setI(Demo demo) {
       demo.index=demo.index-1;
   }
}

大家仔细看一下Demo类的四个方法两个类方法,两个对象方法,这个类主要想象大家说明什么问题呢?其实很简单就是想告诉大家类方法的同步方法与对象方法的同步方法占用的不是同一个锁,一个是类锁,一个是对象锁,因此他们不会出现互相抢占锁的情况。