代码之家  ›  专栏  ›  技术社区  ›  seeker

synchronized关键字如何处理实例变量?

  •  1
  • seeker  · 技术社区  · 6 年前

    我在看一些遗留代码的形式

    public class Client {
      private final Cache cache; 
      .....
       Client( final Cache cache) {
        this.cache = cache;
       }
    
      public Value get(Key key) {
         synchronized(cache){
           return this.cache.get(key);
         }
        }
       public void put(Key k , Value v) {
            synchronized(this.cache){
                return cache.put(k, v);
            }
        }
       }
    }
    

    我从没见过一个实例变量 被改进的 用作锁对象,因为通常锁是最终的对象实例,或者只是通过javaapi直接锁。

    1. 同步关键字在这种情况下有什么影响?不是为的每个实例创建新锁吗 Client 反对?
    2. 使用 synchronized 关键字强制在应用get/put操作之前更新缓存?
    3. 为什么在get之前需要同步?假设另一个线程应用了一个put临时值,就可以将缓存更新为最新的值。
    0 回复  |  直到 6 年前
        1
  •  0
  •   samzz    6 年前

    synchronized 提供相同的保证,无论它是用于静态变量还是实例变量。i、 例如,内存可见性和原子性。在您的例子中,它在实例级别为属性提供线程安全 cache .

    所以,来回答你的问题

    1. 你是对的。的每个实例 Client 会有自己的锁。但当 顾客 在多个客户端之间共享。

    2. 合同执行后 已同步 块,CPU本地缓存将被刷新到主内存中,这确保了其他线程的内存可见性。在开始执行 已同步 块,本地CPU缓存将失效并从主内存加载。所以是的, 已同步 将导致实例变量 隐藏物 以获得最新的值。请看 Synchronization 更多细节。

    3. 原因与2相同。i、 例如,提供内存可见性。