【JAVA】synchronized关键字

最近重新梳理了下java的synchronized相关内容,希望能帮助到有需要的朋友们。

主要阐述以下几个问题:

1.非static方法前加synchronized

1 class Demo{
2     synchronized public void doXXX(){
3         //code…
4     }
5 }
View Code

对于这段代码,我们要考虑这几个问题:

  1. 理解synchronized锁的是什么?
  2. 如果三个线程里分别new了三个Demo对象,各自的run方法里分别执行各自Demo对象的doXXX方法,那么synchronized还起作用吗?
  3. 如果三个线程里共用一个Demo对象,各自的run方法里分别执行这个共用Demo对象的doXXX方法,那么synchronized还起作用吗?

在非static方法前面加synchronized,锁的是这个new出来的Demo对象的本身,也就是this。要执行doXXX方法,必须要先获取对象锁(即对象本身)。

所以,2中doXXX的对象锁来自3个不同的Demo对象,各自线程使用各自Demo对象的锁,不存在共用锁的情况,synchronized不起作用。

同理,3中doXXX的对象锁来自1个相同的Demo对象,各自线程使用同个Demo对象的锁,存在共用锁的情况,synchronized起作用。

 

2.方法内部synchronized同步块

1 class Demo {
2     public void doXXX(){
3         synchronized(this){
4             //code…
5         }
6        }
7 }
8     
View Code

对于这段代码,我们需要考虑这几个问题:

  1. 括号里填this?
  2. 括号里填类.class?
  3. 括号里填一个对象?

synchronized锁住的是括号里的对象,而不是代码。所以多线程情况下要执行doXXX,要先获得锁,即括号里指定的内容。

分析:

  1. 如果填this,多线程共用同一个Demo对象时,可以控制并发操作带来的问题,如果各个线程使用各自的Demo对象时,是没有用的。
  2. 如果填类.class,相当于对类加锁,也就是在该类的所有成员间实现互斥,在同一时间只有一个线程可访问该类的实例(如果需要在线程间相互唤醒就需要借助Object类的wait()方法及nofity()方法),这种方法,不管各个线程使用同一个Demo对象还是使用各自的Demo对象,都可以解决并发操作带来的问题。一般用方法所在类.class或者方法所在类内部定义一个static的对象,作为锁。这种方式称为全局锁。
  3. 对象的情况有很多,可以来自Demo类内部(static和非static),外部传入(static和非static),但是要传哪种,相信你看完上面两条分析,心里应该有数了。

 

3.static方法前加synchronized

1 class Demo{
2     public static synchronized void doXXX{
3         //code…
4         }
5 }
6     
View Code

static的synchronized方法,所以它锁的不是this,而是类的Class对象,而且方法中无法使用this。可见,这种方式不管new几个Deom调用doXXX,都不会并发。

 

相信你理解了上面三个问题,那么你对synchronized关键字就有了一定的了解,并能够将它运用在处理并发操作的问题上了。

 

 

 

-----------------------------------------------------

请尊重作者劳动成果,

转载请注明出处:http://www.cnblogs.com/ryanyu/p/6647121.html

posted @ 2017-03-30 17:08  加勒比海龟  阅读(221)  评论(0编辑  收藏  举报