关于synchronized,“锁住了谁”

突然,我遇到了sychronized关键字。

“对它的理解模模糊糊,似懂非懂”,这是我之前的感觉,但是百度了一波后,发现我对它真的是一无所知。

(前言)sychronized应用最常见的地方:1,sychronized方法;2,sychronized代码块。(这里先不讨论static关键字的东西,因为很多大手已经解释得很好了,不再费口舌,本文所有代码都默认为非静态。)sychronized代码块又有两种情况:1,sychronized(this);2,sychronized(object)。所以,其实sychronized最常见的“用法”有三点。

问题:锁住了谁?

最初,我以为sychronized方法是锁住了方法,任何执行到那个方法的线程都会进入阻塞态;sychronized(this)锁住了代码块所在的方法所在的对象,任何执行到那个对象的线程都会进入阻塞态;sychronized(object)锁住了object,任何执行到object的线程都会进入阻塞态。

事实并不是这样,可能很多人要牢骚了,既然不是这样,为什么还要费口舌,难道是为了误导?或者仅仅是记录自己原来的错误理解?当然我要为自己洗白:其实我的错误虽然没发生在你身上,但是有可能发生在其他人身上,其实我百度了好长时间,发现确实有很多人都是这么理解的,而且评论席里还有各种“666”,所以,可能你身边很多人对synchronized的理解都是不太恰当的,我们都不是独立完成整个项目的开发者,知道别人潜在的错误是很重要的。

其实前两种“用法”大家的意见都比较统一:sychronized方法和synchronized(this)锁住的是方法所属对象的所有synchronized方法和synchronized(this)代码块。这里,很多人强调“并不是锁住了代码而是锁住了对象”,但是我不知道这句话的“实际意义”是什么,我也没看明白他们为什么要强调,反而我感觉这种强调是在咬文嚼字以致更难理解。实际上,当一个线程进入到synchronized方法或synchronized(this)时,并不是其他线程“调用此对象时一定会进入阻塞态”,其他线程调用此对象的非sychronized方法或非synchronized代码块都会顺利运行,不会进入阻塞态,而“其他线程调用此对象的synchronized方法或者synchronized(this)代码块会进入阻塞态”。synchronized(this)和synchronized方法一样,只是synchronized(this)的锁定范围“更精确一些”。应用场景不同,但是锁住的东西是一样的。

到这里,问题就集中在synchronized(object)锁住了谁?这也是我之前一直疑惑的地方。

上码,快准狠。(百度了好长时间,却一直没想过自己实验,实在没办法了,才去动手码字,发现比看一百篇软文有用多了)。

……

经过实验,发现,synchronized(object)锁住的是“当前对象的synchronized(object)代码块”,这句话看起来真的很像废话。但是却有太多人没弄明白,其实真相是如此简单。它包含了两个条件:1,当前对象;2,synchronized(object)代码块。经过实验,我发现:当一个线程进入synchronized(object)时,其他线程是可以进入其他synchronized方法或者synchronized(this)代码块的,而且,当一个线程进入synchronized方法或者synchronized方法时,其他线程也可以进入synchronized(object)代码块。这说明synchronized(object)和其他两种情况是不一样的,很多人都遗漏了这一点,以为是锁住了object。

语言是强大的,是我的信仰,但是我并不能很好的运用,至少在这个问题上,我并不能用语言表达我的理解,也建议各位遇到问题时,百度虽是第一选择,但有些问题,动手码字,把自己想法种的可能性码出来,运行一下,所有东西都会更清晰且真实的展现出来。

发布了44 篇原创文章 · 获赞 25 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/csdn372301467/article/details/78997706