自动采集更新的网站wordpress,健身网站开发背景及意义,电子商务网站建设与实践,畜牧业网站模板synchronized实现原理
Java中每一个对象都可以作为锁#xff0c;这是synchronized实现同步的基础#xff1a;
普通同步方法#xff0c;锁是当前实例对象静态同步方法#xff0c;锁是当前类的class对象同步方法块#xff0c;锁是括号里面的对象 当一个线程访问同步代码块…synchronized实现原理
Java中每一个对象都可以作为锁这是synchronized实现同步的基础
普通同步方法锁是当前实例对象静态同步方法锁是当前类的class对象同步方法块锁是括号里面的对象 当一个线程访问同步代码块时它首先是需要得到锁当退出或者抛出异常时必须要释放锁那么它是如何来实现这个机制的呢我们先看一段简单的代码
package cn.alibab.javap;public class SynchronizedTest {public synchronized void test1(){}public void test2(){synchronized (this){}}
} 利用javap工具javap是java编译之后的class文件的分解器查看生成的class文件信息来分析Synchronized的实现 从上面可以看出同步代码块是使用monitorenter和monitorexit指令实现的同步方法在这看不出来需要看JVM底层实现依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。
同步代码块monitorenter指令是在编译后插入到同步代码块的开始位置monitorexit指令插入到同步代码块的结束位置JVM需要保证每一个monitorenter都有一个monitorexit与之相对应。任何对象都有一个monitor与之相关联当且一个monitor被持有之后他将处于锁定状态。线程执行到monitorenter指令时将会尝试获取对象所对应的monitor所有权即尝试获取对象的锁【摘自并发编程艺术】
同步方法synchronized方法则会被翻译成普通的方法调用和返回指令如:invokevirtual、areturn指令在VM字节码层面并没有任何特别的指令来实现被synchronized修饰的方法而是在Class文件的方法表中将该方法的access_flags字段中的synchronized标志位置1表示该方法是同步方法并使用调用该方法的对象或该方法所属的Class在JVM的内部对象表示Klass做为锁对象。(摘自http://www.cnblogs.com/javaminer/p/3889023.html)
synchronized和lock的区别 区别如下 来源 lock是一个接口而synchronized是java的一个关键字synchronized是内置的语言实现 异常是否释放锁 synchronized在发生异常时候会自动释放占有的锁因此不会出现死锁而lock发生异常时候不会主动释放占有的锁必须手动unlock来释放锁可能引起死锁的发生。所以最好将同步代码块用try catch包起来finally中写入unlock避免死锁的发生。 是否响应中断 lock等待锁过程中可以用interrupt来中断等待而synchronized只能等待锁的释放不能响应中断 是否知道获取锁 Lock可以通过trylock来知道有没有获取锁而synchronized不能 Lock可以提高多个线程进行读操作的效率。可以通过readwritelock实现读写分离 在性能上来说如果竞争资源不激烈两者的性能是差不多的而当竞争资源非常激烈时即有大量线程同时竞争此时Lock的性能要远远优于synchronized。所以说在具体使用时要根据适当情况选择。 synchronized使用Object对象本身的wait 、notify、notifyAll调度机制而Lock可以使用Condition进行线程之间的调度
//Condition定义了等待/通知两种类型的方法
Lock locknew ReentrantLock();
Condition conditionlock.newCondition();
...
condition.await();
...
condition.signal();
condition.signalAll(); 1、synchronized和lock的用法区别
synchronized在需要同步的对象中加入此控制synchronized可以加在方法上也可以加在特定代码块中括号中表示需要锁的对象。
lock一般使用ReentrantLock类做为锁。在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。
2、synchronized和lock性能区别
synchronized是托管给JVM执行的 而lock是java写的控制锁的代码。
在Java1.5中synchronize是性能低效的。因为这是一个重量级操作需要调用操作接口导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象性能更高一些。
但是到了Java1.6发生了变化。synchronize在语义上很清晰可以进行很多优化有适应自旋锁消除锁粗化轻量级锁偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示他们也更支持synchronize在未来的版本中还有优化余地。
2种机制的具体区别synchronized原始采用的是CPU悲观锁机制即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换当有很多线程竞争锁的时候会引起CPU频繁的上下文切换导致效率很低。
而Lock用的是乐观锁方式。所谓乐观锁就是每次不加锁而是假设没有冲突而去完成某项操作如果因为冲突失败就重试直到成功为止。乐观锁实现的机制就是CAS操作Compare and Swap。我们可以进一步研究ReentrantLock的源代码会发现其中比较重要的获得锁的一个方法是compareAndSetState。这里其实就是调用的CPU提供的特殊指令。
现代的CPU提供了指令可以自动更新共享数据而且能够检测到其他线程的干扰而 compareAndSet() 就用这些代替了锁定。这个算法称作非阻塞算法意思是一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。
3、synchronized和lock用途区别
synchronized原语和ReentrantLock在一般情况下没有什么区别但是在非常复杂的同步应用中请考虑使用ReentrantLock特别是遇到下面2种需求的时候。
1.某个线程在等待一个锁的控制权的这段时间需要中断 2.需要分开处理一些wait-notifyReentrantLock里面的Condition应用能够控制notify哪个线程 3.具有公平锁功能每个到来的线程都将排队等候
下面细细道来……
先说第一种情况ReentrantLock的lock机制有2种忽略中断锁和响应中断锁这给我们带来了很大的灵活性。比如如果A、B 2个线程去竞争锁A线程得到了锁B线程等待但是A线程这个时候实在有太多事情要处理就是一直不返回B线程可能就会等不及了想中断自己不再等待这个锁了转而处理其他事情。这个时候ReentrantLock就提供了2种机制可中断/可不中断 第一B线程中断自己或者别的线程中断它但是ReentrantLock不去响应继续让B线程等待你再怎么中断我全当耳边风synchronized原语就是如此 第二B线程中断自己或者别的线程中断它ReentrantLock处理了这个中断并且不再等待这个锁的到来完全放弃。