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. Codeforces - 702A - Maximum Increase - 简单dp

    DP的学习计划,刷 https://codeforces.com/problemset?order=BY_RATING_ASC&tags=dp 遇到了这道题 https://codeforce ...

  2. spring-data-redis 使用过程中踩过的坑

    spring-data-redis简介 Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, ...

  3. ASI框架的使用

    iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...

  4. 手机测试用例-STK测试用例

    ID 功能描述 操作步骤 预期结果 test time P/F comment tester test time P/F comment tester STK服务 SIM卡适应性测试 1.选取支持ST ...

  5. Java笔记-序列化的注意点

    1.使用serialVersionUID 在Eclipse中,如果一个类实现了Serializable接口,且没有给这个类设置一个serialVersionUID,就会有一个警告标志: The ser ...

  6. bzoj 5019 [Snoi2017]遗失的答案

    题面 https://www.lydsy.com/JudgeOnline/problem.php?id=5019 题解 如果L不是G的倍数 答案为0 下面考虑G|L的情况 将G,L质因数分解 设$L= ...

  7. JavaScript中简单排序总结

    JavaScript中简单排序总结 冒泡排序 经典排序算法, 双重for循环 在第二个for循环的时候, j < arr.len -1 -i , 这一步的优化很重要 function bullS ...

  8. 18.3.2从Class上获取信息(注解)

    package d18_3_1; /** * Class类上所包含的注解 * * getAnnotation(Class annotationClass) 获取该元素上指定的类型的注解 * getAn ...

  9. java 环境变量的设置,备忘

    新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.7.0变量名:CLASSPATH 变量值:.;%JAVA ...

  10. zoj3768Continuous Login

    链接 这题通过暴力可以看出最多不超过3 具体为什么..等着看大牛的题解. 可以预处理出来两个数之和 用bool存下 然后枚举一个数 二分剩余数的位置就可以了 勉强可过 #include <ios ...