看过很多关于java并发编程的博客以及一些书籍,但是因为平时接触并发编程比较少,所以一些知识很快就遗忘了。我想,如果能从原理或底层实现上理解并发,那么,到需要应用的时候,就能够很快的理解使用了。
首先来说synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,通过对对象的头文件来操作,从而达到加锁和释放锁的目的。它是一种悲观锁的实现,即一开始就认为会有多个线程同时对数据进行操作,使用互斥的策略对其进行同步:即同一时间,只有一个线程可以操作临界数据,其余访问的线程则阻塞等待锁的释放,这导致了synchronized效率比较低。在JDK1.6版本中,对synchronized加入了很多优化措施,有自适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等,使得synchronized的性能并不比Lock差。synchronized在java中的使用分为synchronized代码快以及synchronized方法,锁的释放是在代码块或者方法执行完后自动释放又或者是执行代码过程中出现异常jvm释放锁,这说明synchronized中的锁无需手动编写代码释放,jvm已经帮忙进行释放啦。另外synchronized是可重入的,这意味着可以在synchronized代码块或者方法中重复获取已经获取到的锁,不会导致死锁。
Lock并不是java语言内置的,它是一个接口,其实现定义在java.util.concurrent包下的各个类中,如ReetrantLock,ReentrantReadWriteLock等。这里说说concurrent包,该包下的类的实现大多依赖于CAS操作,如一些原子类AtomicInteger、A tomicLong等,实现的流程是通过jni调用c/c++代码,进而调用内核代码实现。因为CAS的实现依赖于底层cpu指令集。回到Lock,对比与synchronized,Lock是一种基于冲突检测的乐观并发策略,俗地讲就是先进性操作,如果没有其他线程争用共享数据,那操作就成功了,如果共享数据被争用,产生了冲突,那就再进行其他的补偿措施(最常见的补偿措施就是不断地重拾,直到试成功为止),这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步被称为非阻塞同步。ReetrantLock采用的便是这种并发策略。Lock需要自己管理锁的释放unlock(),否则会出现死锁,但是这种可控的操作使得线程可以判断是否自己获取到了锁(sychronized不可以)。
引用自:
强烈推荐!---原文链接
有关CAS---原文链接