Lock的锁定是通过代码实现的,而 synchronized 是在 JVM 层面上实现的
synchronized在锁定时如果方法块抛出异常,JVM 会自动将锁释放掉,不会因为出了异常没有释放锁造成线程死锁。但是 Lock 的话就享受不到 JVM 带来自动的功能,出现异常时必须在 finally 将锁释放掉,否则将会引起死锁。
在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的。原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不管用没用过5.0多线程包的程序员都能理解。 
ReentrantLock
ReentrantLock提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。 
Atomic
和上面的类似,不激烈情况下,性能比synchronized略逊,而激烈的时候,也能维持常态。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。但是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。因为他不能在多个Atomic之间同步。 
Lock的使用参见下面的代码(把lock换成synchronized的效果是一样的):
  1. import java.util.concurrent.TimeUnit;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. public class Resource3 {
  5. private Lock lock = new ReentrantLock();
  6. public void f() {
  7. // other operations should not be locked...
  8. System.out.println(Thread.currentThread().getName()
  9. + ":not synchronized in f()");
  10. lock.lock();
  11. try {
  12. for (int i = 0; i < 5; i++) {
  13. System.out.println(Thread.currentThread().getName()
  14. + ":synchronized in f()");
  15. try {
  16. TimeUnit.SECONDS.sleep(3);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. } finally {
  22. lock.unlock();
  23. }
  24. }
  25. public void g() {
  26. // other operations should not be locked...
  27. System.out.println(Thread.currentThread().getName()
  28. + ":not synchronized in g()");
  29. lock.lock();
  30. try {
  31. for (int i = 0; i < 5; i++) {
  32. System.out.println(Thread.currentThread().getName()
  33. + ":synchronized in g()");
  34. try {
  35. TimeUnit.SECONDS.sleep(3);
  36. } catch (InterruptedException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. } finally {
  41. lock.unlock();
  42. }
  43. }
  44. public void h() {
  45. // other operations should not be locked...
  46. System.out.println(Thread.currentThread().getName()
  47. + ":not synchronized in h()");
  48. lock.lock();
  49. try {
  50. for (int i = 0; i < 5; i++) {
  51. System.out.println(Thread.currentThread().getName()
  52. + ":synchronized in h()");
  53. try {
  54. TimeUnit.SECONDS.sleep(3);
  55. } catch (InterruptedException e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. } finally {
  60. lock.unlock();
  61. }
  62. }
  63. public static void main(String[] args) {
  64. final Resource3 rs = new Resource3();
  65. new Thread() {
  66. public void run() {
  67. rs.f();
  68. }
  69. }.start();
  70. new Thread() {
  71. public void run() {
  72. rs.g();
  73. }
  74. }.start();
  75. rs.h();
  76. }
  77. }

Java中Synchronized和Lock的使用的更多相关文章

  1. java中synchronized与Lock的异同

    本文转载自java中synchronized与Lock的异同 前言 synchronized和Lock通过互斥保障原子性,能够保护共享数据以实现线程安全,其作用包括保障原子性.可见性.有序性 常见问题 ...

  2. JAVA中synchronized和lock详解

         目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronize ...

  3. Java中synchronized和Lock的区别

    synchronized和Lock的区别synchronize锁对象可以是任意对象,由于监视器方法必须要拥有锁对象那么任意对象都可以调用的方法所以将其抽取到Object类中去定义监视器方法这样锁对象和 ...

  4. Java并发指南4:Java中的锁 Lock和synchronized

    Java中的锁机制及Lock类 锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消 ...

  5. java中synchronized的用法详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

  6. java中synchronized的使用方法与具体解释

    Java语言的keyword.当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多仅仅有一个线程运行该段代码. 一.当两个并发线程訪问同一个对象object中的这个synchronized ...

  7. Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...

  8. java中 synchronized 的使用,确保异步执行某一段代码。

    最近看了个有关访问网络url和下载的例子,里面有几个synchronized的地方,系统学习下,以下内容很重要,记下来. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一 ...

  9. JAVA 中 synchronized 详解

    看到一篇关于JAVA中synchronized的用法的详解,觉得不错遂转载之..... 原文地址: http://www.cnblogs.com/GnagWang/archive/2011/02/27 ...

随机推荐

  1. 算法练习--LeetCode--29. Divide Two Integers

    Divide Two Integers Given two integers dividend and divisor, divide two integers without using multi ...

  2. Linux ubuntu 下寻找 texlive 缺失包 texlive 缺失包(转载)

    转自:http://blog.sina.com.cn/s/blog_87315ca60101d4d1.html 在Linux下用 latex 编译 ××.tex 文件有时候时会提示:  ! LaTeX ...

  3. sql 日历

    /* Formatted on 2013/9/7 20:45:28 (QP5 v5.185.11230.41888) */ SELECT MIN (DECODE (TO_CHAR (DAYS, 'D' ...

  4. FZU2277 Change(dfs序+树状数组)

    传送门 题意 q次操作,操作有两种: 1 v x k:a[v]+=x,a[v']+=x-k(v'是v的子节点)... 2 v:查询\(a[v]mod(10^9+7)\) 分析 子节点增加的值为\(x+ ...

  5. (12)用css设计电子相册 {下}

    本篇学习资料讲解:        延续上一篇的学习资料,仍然介绍 使用css对电子相册进行排版 和 侧面强调“盒子模型.标准流.浮动和定位”的重要性. 上篇学习资料介绍的“阵列模式电子相册”,如果也能 ...

  6. Hexo搭建博客教程(3) - 远程部署到GitHub Pages

    本章讲的是如何将本地的个人项目远程部署到 GitHub Pages,涉及到GitHub的项目仓库.Git的使用,以及Hexo的远程部署等. 1. 安装 hexo-deployer-git 插件 想要将 ...

  7. JavaScript--字符串常用方法总结

    JavaScript--字符串常用方法总结 举例模板: var str = "what are you " var str1 = "sss" var txt = ...

  8. MySQL、SqlServer、Oracle三大主流数据库分页查询 (MySQL分页不能用top,因为不支持)

    一. MySQL 数据库 分页查询MySQL数据库实现分页比较简单,提供了 LIMIT函数.一般只需要直接写到sql语句后面就行了.LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它 ...

  9. 纯js手动分页

    昨天让做个页面,后台提供所有数据,没有做好分页,需要前端js手动分页. 我参考了 http://www.cnblogs.com/jiechn/p/4095029.html 做了些许改动让分页效果更加完 ...

  10. Design Patterns Uncovered: The Chain Of Responsibility Pattern

    Chain of Responsibility in the Real World The idea of the Chain Of Responsibility is that it avoids ...