Java多线程与并发 - Synchronized的使用与原理
2018-02-06 22:09
549 查看
Synchronized的使用
普通同步方法:锁是当前实例对象//锁住的是当前类实例 public synchronized int getNext(){ return value++; }
静态同步方法:锁是当前类的Class对象
//锁住的时当前Class对象 public synchronized static int getNext(){ return value++; }
同步方法块:锁是Synchronized括号里配置的对象
//这里可以锁住任何对象。原因来自原理。 public int getNext(){ synchronized(this){ return value++; } }
理解Synchronized的原理
总的来说是通过对锁对象关联的monitor的取用与释放来实现的。因此Sychroniezd也叫做内置锁。关于monitor(理解为一个有监视作用的互斥量):http://blog.csdn.net/b9x__/article/details/79274672
java中任何一个对象都一个monitor与之关联(潜在关联),当且一个monitor被持有后,它将处于锁定状态,每一个被锁住的对象都会和一个monitor record(线程私有的数据结构)关联。Synchronized(对象)就是获取对象的monitor,synchronized下的代码就意味着放入了monitor监视区域,monitor record中中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用,这时就可以执行monitor监视区域的代码了,这些JVM在后台会自动实现。也就是Synchronized在JVM里的实现都是基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter和MonitorExit指令来实现。MonitorEnter指令插入在同步代码块的开始位置,当代码执行到该指令时,将会尝试获取该对象Monitor的所有权,即尝试获得该对象的锁,对象的锁存放在对象头的标志位Mark Word中(这里还有偏向锁,轻量级锁,自旋锁,Sychronized这个是重量级锁),自然monitorExit指令则插入在方法结束或异常处。
i++字节码指令:
每一个被锁住的对象和一个monitor record关联是通过对象头的MarkWord中的LockWord指向monitor record的起始地址来关联的。
任何一个对象都一个monitor与之关联,而Synchronized又是通过对锁对象关联的monitor的取用与释放来实现的,所以在同步方法块中Synchronized锁住的可以是任何对象。
抛开细节理解:每个对象都有monitor,Synchronized(对象)就是获取对象的monitor,获取到的就可以进去同步块执行(字节码指令monitorenter),执行完后释放对象的monitor(字节码指令monitorexit),这是其他线程才可获取对象的monitor。
相关文章推荐
- Java多线程、并发时使用Synchronized(同步锁)解决资源竞争问题
- 关于JAVA多线程并发synchronized的测试与合理使用
- 关于JAVA多线程并发synchronized的测试与合理使用
- 关于JAVA多线程并发synchronized的测试与合理使用
- Linux下的socket编程实践(九) epoll实现高并发的原理及其使用
- Java并发编程:Synchronized及其实现原理
- Java 并发编程:volatile的使用及其原理
- Java并发编程:Synchronized及其实现原理
- Java多线程-wait(), notify(), notifyAll()、yield()、sleep()、join()、interrupt()原理及使用
- Java 并发编程:volatile的使用及其原理
- Java 并发编程:volatile的使用及其原理
- 深入理解Java并发之synchronized实现原理
- 【Java并发编程】之七:使用synchronized获取互斥锁的几点说明
- Synchronized使用及其实现原理
- Synchronized的使用以及实现原理
- Java并发锁之Volatile的原理与使用
- Java并发编程:Synchronized及其实现原理
- 【Java并发编程】11、volatile的使用及其原理
- Java 并发编程:volatile的使用及其原理解析
- 【死磕Java并发】-----深入分析synchronized的实现原理