我在使用ReentrantLock类对变量进行多线程累加时,调用了lock()和unlock()方法,但读取该变量时我未加锁,结果是能正确执行,代码如下:

  1. public class Main {
  2. private long count;
  3. private ExecutorService pool;
  4. private Lock lock = new ReentrantLock();
  5. /**
  6. * @param args
  7. */
  8. public static void main(String[] args) {
  9. new Main().countThread();
  10. }
  11. public Main() {
  12. pool = Executors.newFixedThreadPool(50);
  13. }
  14. public void countThread() {
  15. for (int i = 0; i < 3000; i++) {
  16. pool.execute(new Runnable() {
  17. @Override
  18. public void run() {
  19. lock.lock();
  20. try {
  21. count++;
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. } finally {
  25. lock.unlock();
  26. }
  27. }
  28. });
  29. }
  30. while (true) {
  31. System.out.println(count);
  32. if (count == 3000) {
  33. break;
  34. }
  35. }
  36. System.out.println(count);
  37. pool.shutdown();
  38. }
  39. }

http://www.infoq.com/cn/articles/java-memory-model-1 
这篇文章介绍了Java内存模型定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。 
能不能这样理解,类中的全局变量是存储在主内存。也就是读操作不需要锁,不知道理解是否正确。

合理解释:

主存的变量,线程的本地内存会有一个副本这没错.可是两者有一个同步时机的问题,所以你这样用是不安全的.

要么两边都同步保护,要么你增加"volatile"关键字提示这个变量不能创建本地副本.

[转]关于ReentrantLock中线程读某个变量是否需要加锁的更多相关文章

  1. Java 并发包中的读写锁及其实现分析

    1. 前言 在Java并发包中常用的锁(如:ReentrantLock),基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时 刻可以允许多个读线程访问,但是在写线程访问时,所有 ...

  2. Java中的读写锁

    一.读写锁 1.初识读写锁 a)Java中的锁——Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进 ...

  3. Java并发包中线程池ThreadPoolExecutor原理探究

    一.线程池简介 线程池的使用主要是解决两个问题:①当执行大量异步任务的时候线程池能够提供更好的性能,在不使用线程池时候,每当需要执行异步任务的时候直接new一个线程来运行的话,线程的创建和销毁都是需要 ...

  4. java中ReentrantReadWriteLock读写锁的使用

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...

  5. Java线程:条件变量、原子量、线程池等

    一.条件变量 条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件 ...

  6. MFC 中线程传递CString 是不安全的 转

     MFC 中线程传递CString 是不安全的       在MFC中,向线程传递CString变量参数时,很容易犯一个错误,就是使用一个超出生存期的变量,在主函数中定义的CString变量是局部变量 ...

  7. java中线程和并发面试题

    http://www.cnblogs.com/dolphin0520/p/3932934.html http://www.cnblogs.com/dolphin0520/p/3958019.html ...

  8. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  9. Java 中线程安全问题

    不好意思,一个国庆假期给我放的都不知道东西南北了,放松,很放松,差一点就弃更了,感谢那些催更的小伙伴们! 虽然没有更新,但是日常的学习还是有的,以后我尽量给大家分享一些通用知识,非技术. 但是本期还是 ...

随机推荐

  1. Intellij idea 添加浏览器

    最近的项目要做一个海康的网页端的监控,需要下载海康的插件,但是试验了一下,Chrome和IE的都不支持插件的显示,只有搜狗的显示,但是Idea的默认浏览器里面没有,所以要添加一个默认的浏览器 方法很简 ...

  2. 3. 使用vue-cli创建项目

    eslint: 用来做项目编码规范检查的工具基本原理: 定义了很多规则, 检查项目的代码一旦发现违背了某个规则就输出相应的提示信息有相应的配置, 可定制检查 1. 创建项目 vue脚手架(vue-cl ...

  3. C++.可变参数_ZC测试

    ZC:环境: Win7 x64(旗舰版),Microsoft Visual Studio 2010(版本 10.0.30319.1 RTMRel, Microsoft .NET Framework(版 ...

  4. try....fail....catch...Assert 模式的测试, fail是Junit中的功能

    try { // 反射读取properties文件 new BufferedReader(new FileReader(myConfigPath[4])); //上面没有抛出异常就是执行fail, / ...

  5. 记录flask使用模板时出现的“Internal Server Error”错误

    在看<Flask Web开发实战:入门.进阶与原理解析(李辉著 )>时照着书上的代码抄了一遍,然后运行时发现一直出现以下的错误 书上的源代码如下 watchlist.html <he ...

  6. Vue技巧

    转载:https://segmentfault.com/a/1190000014085613?utm_source=channel-hottest 对自己有用,做个笔记,有兴趣可以去以上地址去看. 第 ...

  7. 使用pipeline减少与redis交互次数

    1.redis_pipeline=redis_cli.pipeline() 2.redis_pipeline.setex()此语句可写多条 3.redis_pipeline.execute() # # ...

  8. CSS sprite使用

    CSS Sprites叫css精灵或者雪碧图,是一种网页图片应用处理方式. CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”, ...

  9. Unity中的粒子特效的 RendererQ 排序

    这里接https://www.cnblogs.com/luguoshuai/p/10021660.html 这里介绍两套粒子排序的方法. 首先声明,这两套排序方法均不是本人所写,是在项目开发的过程当中 ...

  10. spring集成JMS访问ActiveMQ

    首先我们搭建一个spring-mvc项目,项目可以参考:spring-mvc 学习笔记 步骤: 在pom.xml中加上需要的包 修改web.xml,增加IOC容器 spring配置文件applicat ...