Java并发编程:Synchronized及其实现原理

  • 时间:
  • 浏览:5
  • 来源:大发排列3_大发排列3官方

执行结果如下,其实tcp连接1和tcp连接2都进入了对应的依据 刚开始英语 执行,否则 tcp连接2在进入同步块完后 ,需要等待时间tcp连接1中同步块执行完成。

Method 1start

Method 1execute

Method 2start

Method 1end

Method 2execute

Method 2end

  执行结果如下,对静态依据 的同步本质上是对类的同步(静态依据 本质上是属于类的依据 ,而总要对象上的依据 ),全都即使test和test2属于不同的对象,否则 它们都属于SynchronizedTest类的实例,全都也还不能了顺序的执行method1和method2,还不能了并发执行。

3、静态依据 (类)同步

代码段三:

三、运行结果解释

  有了对Synchronized原理的认识,再来看底下的tcp连接就还不能 迎刃而解了。

1、代码段2结果:

  其实method1和method2是不同的依据 ,否则 一点个多依据 都进行了同步,否则 是通过同有有1个对象去调用的,全都调用完后 都需要先去竞争同有有1个对象上的锁(monitor),也就还不能了互斥的获取到锁,否则 ,method1和method2还不能了顺序的执行。

2、代码段3结果:

  其实test和test2属于不同对象,否则 test和test2属于同有有1个类的不同实例,因为method1和method2都属于静态同步依据 ,全都调用的完后 需要获取同有有1个类上monitor(每个类只对应有有1个class对象),全都也还不能了顺序的执行。

3、代码段4结果:

Method 1start

Method 1execute

Method 1end

Method 2start

Method 2execute

Method 2end

2、对普通依据 同步:

代码段二:

 对于代码块的同步实质上需要获取Synchronized关键字底下括号中对象的monitor,因为这段代码中括号的内容总要this,而method1和method2又是通过同一的对象去调用的,全都进入同步块完后 需要去竞争同有有1个对象上的锁,否则 还不能了顺序执行同步块。

二、Synchronized 原理

  因为对底下的执行结果还有大间题,也先不要急,亲戚亲戚朋友先来了解Synchronized的原理,再回身旁面的大间题就一目了然了。亲戚亲戚朋友先通过反编译下面的代码来看看Synchronized是何如实现对代码块进行同步的:

1 package com.paddx.test.concurrent; 2 3 public class SynchronizedDemo { 4 public void method() { 5 synchronized (this) { 6 System.out.println("Method 1 start"); 7 } 8 } 9 }

反编译结果:



关于这两条指令的作用,亲戚亲戚朋友直接参考JVM规范中描述:

monitorenter :

Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:

• If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.

• If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.

• If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.

这段话的最少意思为:

每个对象有有1个多监视器锁(monitor)。当monitor被占用时就会地处锁定状态,tcp连接执行monitorenter指令时尝试获取monitor的所有权,过程如下:

1、因为monitor的进入数为0,则该tcp连接进入monitor,否则 将进入数设置为1,该tcp连接即为monitor的所有者。

2、因为tcp连接因为占有该monitor,假如有一天重新进入,则进入monitor的进入数加1.

3.因为一点tcp连接因为占用了monitor,则该tcp连接进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

monitorexit: 

The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.

The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

这段话的最少意思为:

执行monitorexit的tcp连接需随后objectref所对应的monitor的所有者。

指令执行时,monitor的进入数减1,因为减1后进入数为0,那tcp连接退出monitor,不再是一点monitor的所有者。一点被一点monitor阻塞的tcp连接还不能 尝试去获取一点 monitor 的所有权。

  通过这两段描述,亲戚亲戚朋友应该能很清楚的看出Synchronized的实现原理,Synchronized的语义底层是通过有有1个monitor的对象来完成,其实wait/notify等依据 也依赖于monitor对象,这假如有一天为一点还不能了在同步的块因为依据 中不能调用wait/notify等依据 ,否则 会抛出java.lang.IllegalMonitorStateException的异常的因为。

  亲戚亲戚朋友再来看一下同步依据 的反编译结果:

源代码:

1 package com.paddx.test.concurrent; 2 3 public class SynchronizedMethod { 4 public synchronized void method() { 5 System.out.println("Hello World!"); 6 } 7 }

反编译结果:



  从反编译的结果来看,依据 的同步并这么通过指令monitorenter和monitorexit来完成(理论上其实也还不能 通过这两条指令来实现),不过相对于普通依据 ,其常量池中多了ACC_SYNCHRONIZED标示符。JVM假如有一天根据该标示符来实现依据 的同步的:当依据 调用时,调用指令因为检查依据 的 ACC_SYNCHRONIZED 访问标志算是被设置,因为设置了,执行tcp连接将先获取monitor,获取成功完后 不能执行依据 体,依据 执行完后 再释放monitor。在依据 执行期间,一点任何tcp连接都无法再获得同有有1个monitor对象。 其实本质上这么区别,假如有一天依据 的同步是并算是隐式的依据 来实现,不要通过字节码来完成。

执行结果如下,tcp连接1和tcp连接2同时进入执行状态,tcp连接2执行速率单位比tcp连接1快,全都tcp连接2先执行完成,一点过程中tcp连接1和tcp连接2是同时执行的。

四 总结

  Synchronized是Java并发编程中最常用的用于保证tcp连接安全的依据 ,其使用相对也比较简单。否则 因为不能深入了解其原理,对监视器锁等底层知识有所了解,一方面还不能 帮助亲戚亲戚朋友正确的使用Synchronized关键字,当时人面随可否 帮助亲戚亲戚朋友更好的理解并发编程机制,不利于亲戚亲戚朋友在不同的状态下选择更优的并发策略来完成任务。对平时遇到的各种并发大间题,随可否 从容的应对。

4、代码块同步

代码段四:

Method 1start

Method 1execute

Method 2start

Method 2execute

Method 2end

Method 1end

一、Synchronized的基本使用

  Synchronized是Java中避免并发大间题的并算是最常用的依据 ,也是最简单的并算是依据 。Synchronized的作用主要有有1个多:

(1)确保tcp连接互斥的访问同步代码

(2)保证共享变量的修改不能及时可见

(3)有效避免重排序大间题。从语法上讲,Synchronized总共有并算是用法:

  (a)修饰普通依据

  (b)修饰静态依据

  (c)修饰代码块

  接下来让我通过多少例子tcp连接来说明一下这并算是使用依据 (为了便于比较,三段代码除了Synchronized的使用依据 不同以外,一点基本保持一致)。

1、这么同步的状态:

代码段一:

执行结果如下,跟代码段一比较,还不能 很明显的看出,tcp连接2需要等待时间tcp连接1的method1执行完成不能刚开始英语 执行method2依据 。

Method 1start

Method 1execute

Method 1end

Method 2start

Method 2execute

Method 2end