[转]关于ReentrantLock中线程读某个变量是否需要加锁

时间:2023-03-09 04:32:06
[转]关于ReentrantLock中线程读某个变量是否需要加锁

我在使用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"关键字提示这个变量不能创建本地副本.