位置: 建议127: Lock与synchronized是不一样的

首先在概念上纠正这一篇内容:

援引Java源码中关于ReentrantLock的开篇说明:

* A reentrant mutual exclusion {@link Lock} with the same basic
 * behavior and semantics as the implicit monitor lock accessed using
 * {@code synchronized} methods and statements, but with extended
 * capabilities.

根据说明: 两个加锁方式是具有相同的基础行为和语义的,仅仅是表现形式上和功能扩展性方面的差别,所以该建议理论是错误的.

以下代码段的执行差异和原作者的解释错误主要出现在以下几个方面:

1.  ReentrantLock和synchronized 都是对象级所,而没有一个是类级的,因此都只能作用到代码所影响的具体对象上去.

  如 synchronized public void read(){

    // some executing code region

  } 其实是隐式锁定了this;

  等价于:

  Lock lock = new ReentrantLock();

  public void read(){

    lock.lock();

    try{

      // some executing code region

    }finally{

      lock.unlock();

    }

  }

  两者的区别是一个monitorthis, 一个monitor lock对象.

比较特殊的情况是:

synchronized publi static execute(){

  

}

该类对象锁定的是 .class对象.

下文中的不一致性主要出现在对"A"的synchronized锁定上,

常量字符串对象在整个生命周期内是全局唯一的,因此,对"A"的所是全局生效的,不仅仅在次类内部,及时全局任何对synchronized("A")都会产生同步效果,这里违反了封闭原则,因此具有巨大的编程风险.

援引代码错误:

该篇引用了两段代码来说明两种方式的行为不一致性.

在这里简单地列举并指出问题所在:

class1 : lock

/*****************************************************************************/

class Task {

  public void doSomething(){

    try{

      Thread.sleep(2000);

    }catch(Exception e){

      // 异常处理

    }

    StringBuilder sb = new StringBuilder();

    // 线程名称:

    sb.append(" 线程名称: " + Thread.currentThread().getName());

    // 运行时间戳

    sb.append(",执行时间: " + Calendar.getInstance().get(13) + " s");

    System.out.println(sb.toString());

  }

}

/****************************************************************************/

class TaskWithLock extends Task implements Runnable{

  private final Lock lock = new ReentrantLock();

  @Override

  public void run(){

    try{

      // 开始锁定

      lock.lock();

      doSomething();

    }finally{

      // 释放锁

      lock.unlock();

    }

  }

}

/***************************************************************************/

class TaskWithSync extends Task implements Runnable{

  @Override

  public void run(){

    // 内部索

    synchronized("A"){

      doSomething();

    }

  }

}

public static void runTasks(Class<? extends Runnable> clazz) throws Exception {

  try{

  ExecutorService es = Executors.newCachedThreadPool();

  System.out.println("***开始执行" + clazz.getSimpleName() + " 任务已执行完毕-----------------\n");

  // 启动三个线程

  for ( int i=0; i<3 ; i++){

    es.submit(clazz.newInstance());

  }

  TimeUnit.SECONDS.sleep(10);

  System.out.println("--------" + clazz.getSimpleName() + " 任务执行完毕------\n");

  // 关闭执行器

  }finally{

    es.shutdown();

  }

}

秦晓波著的编写高质量代码-改善Java程序的151个建议一书中的线程解释错误.的更多相关文章

  1. 编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础

    原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks The reasonable man adapts himse ...

  2. 博友的 编写高质量代码 改善java程序的151个建议

    编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html

  3. 编写高质量代码改善java程序的151个建议——导航开篇

    2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...

  4. 编写高质量代码:改善Java程序的151个建议 --[117~128]

    编写高质量代码:改善Java程序的151个建议 --[117~128] Thread 不推荐覆写start方法 先看下Thread源码: public synchronized void start( ...

  5. 编写高质量代码:改善Java程序的151个建议 --[106~117]

    编写高质量代码:改善Java程序的151个建议 --[106~117] 动态代理可以使代理模式更加灵活 interface Subject { // 定义一个方法 public void reques ...

  6. 编写高质量代码:改善Java程序的151个建议 --[78~92]

    编写高质量代码:改善Java程序的151个建议 --[78~92] HashMap中的hashCode应避免冲突 多线程使用Vector或HashTable Vector是ArrayList的多线程版 ...

  7. 编写高质量代码:改善Java程序的151个建议 --[65~78]

    编写高质量代码:改善Java程序的151个建议 --[65~78] 原始类型数组不能作为asList的输入参数,否则会引起程序逻辑混乱. public class Client65 { public ...

  8. 编写高质量代码:改善Java程序的151个建议 --[52~64]

    编写高质量代码:改善Java程序的151个建议 --[52~64] 推荐使用String直接量赋值 Java为了避免在一个系统中大量产生String对象(为什么会大量产生,因为String字符串是程序 ...

  9. 编写高质量代码:改善Java程序的151个建议 --[36~51]

    编写高质量代码:改善Java程序的151个建议 --[36~51] 工具类不可实例化 工具类的方法和属性都是静态的,不需要生成实例即可访 问,而且JDK也做了很好的处理,由于不希望被初始化,于是就设置 ...

随机推荐

  1. JRE System Library 与Java EE Libraries的区别

    JRE System Library是只要做java开发都需要的完整的.标准的库.  Java EE5 Libraries只是java三个方向中做java EE所需要的库.如果做Web方面的开发的话就 ...

  2. 各种java生成word解决方案的优缺点对比

    解决方案 优点 缺点 Jacob 功能强大 直接调用VBA接口,程序异常复杂:服务器必须是:windows系统+安装Office:服务器端自动化com接口容易产生死进程造成服务器宕机 Apache P ...

  3. Gym - 100342J:Triatrip(Bitset加速求三元环的数量)

    题意:求有向图里面有多少个三元环. 思路:枚举起点A,遍历A可以到的B,然后求C的数量,C的数量位B可以到是地方X集合,和可以到A的地方Y集合的交集(X&Y). B点可以枚举,也可以遍历.(两 ...

  4. Android Studio自动生成带系统签名的apk

    介绍签名的两种方式: 1.signapk.jar命令行方式: 如果你需要开发一个带有系统权限的app,往往需要配置SharedUserId,比如: </pre><pre name=& ...

  5. 单选框 复选框 隐藏之后,绑定的change事件在ie中失效的问题

    有时候需要对单选框和复选框进行美化,就需要在<input type="radio">和<input type="checkbox">元素 ...

  6. 【旧文章搬运】360安全卫士HookPort.sys完美逆向

    原文发表于百度空间,2009-11-08 这是第一次逆向一个企业级安全产品的核心代码,并完美替换原驱动正常工作============================================= ...

  7. pymssql读取varchar字段中文显示乱码的问题分析

    问题 用python的pymssql模块读取旧业务系统后台SQL Server 2000数据库展示数据为乱码 开发环境 操作系统:windows 8 数据库 MS SQL Server 2000,默认 ...

  8. 死记硬背之Bunside

    就是 本质不同的个数为 $$\frac{1}{|G|} \cdot \sum_{|s| \in |G|}{ C(|s|) }$$ 所以,虽然不知道为啥,但是等价类的个数为 $$\sum_{i=1}^{ ...

  9. Programming With Objective-C---- Encapsulating Data ---- Objective-C 学习(三) 封装数据

      Programming with Objective-C Encapsulating Data In addition to the messaging behavior covered in t ...

  10. 洛谷 - P1355 - 神秘大三角 - 简单计算几何

    https://www.luogu.org/problemnew/show/P1355 判断一个点和三角形的位置关系,最简单的思路就是用向量. 首先排除掉和三角形顶点重合的情况. 把三角形设计成一个首 ...