×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

2个错误: 1.在读数据时也要加锁, 2. 对 static变量应该是用类加锁而不是对象加锁.

1. 由于 counter是 static变量, 这里应该是对类加锁,而不是对象加锁.所以对counter的读写必须 synchronized static 方法. 否则可以同时有多个 IncrementImpl 对象可以同时调用increment()方法, 因为它们有各自的对象锁,不存在互斥的问题. 这样一来,就违反了程序对共享数据加锁的本来意图.

2. 在访问操作时,也应该加锁,用synchronized, 因为increment()不是原子操作, 另外的线程有可能在任意时刻读数据, 就会读取不稳定的中间状态的值.

正确的应该是:

public class IncrementImpl {
private static int counter = 0;
public synchronized static void increment() {
counter++;
}
public int synchronized static getCounter() {
return counter;
}
}
Report

Replies, comments and Discussions:

  • 工作学习 / IT技术讨论 / Java兄弟们,给大家一道在线面试题,看大家要几秒钟。。。(记着:对方正等你做完,给你下一道)
    2. This class (IncrementImpl) will be used by various threads
    concurrently; can you see the inherent flaw(s)? How would you improve it?

    public class IncrementImpl {
    private static int counter = 0;
    public synchronized void increment() {
    counter++;
    }
    public int getCounter() {
    return counter;
    }
    }
    • 如果有几个thread排队要increment(), 另一个thread可以get, 但是它得到的值已经不准确~~
    • 2个错误: 1.在读数据时也要加锁, 2. 对 static变量应该是用类加锁而不是对象加锁.
      1. 由于 counter是 static变量, 这里应该是对类加锁,而不是对象加锁.所以对counter的读写必须 synchronized static 方法. 否则可以同时有多个 IncrementImpl 对象可以同时调用increment()方法, 因为它们有各自的对象锁,不存在互斥的问题. 这样一来,就违反了程序对共享数据加锁的本来意图.

      2. 在访问操作时,也应该加锁,用synchronized, 因为increment()不是原子操作, 另外的线程有可能在任意时刻读数据, 就会读取不稳定的中间状态的值.

      正确的应该是:

      public class IncrementImpl {
      private static int counter = 0;
      public synchronized static void increment() {
      counter++;
      }
      public int synchronized static getCounter() {
      return counter;
      }
      }