java - 在静态变量中使用同步

标签 java multithreading static-variables

我有一个静态 map

private static Map<String, Car> cars = new HashMap<~>() //Map holding car objects

我在像

这样的方法中使用变量
private static String getCar(String name){
    return cars.get(name);
}

所以,如果我想锁定汽车,为了线程安全,可以像下面那样做吗?

private static void xyz() {
    synchronized(cars) {
        Car c = getCar("abc");
        c.setColor("Green");
    }
}

有什么建议吗?

最佳答案

Java 的 synchronized 关键字可以应用于任何对象,以便在继续之前“获取该对象的锁”(或“同步”该对象)。如果任何其他进程试图同时在同一个对象上运行同步代码,它将阻塞,直到锁定该对象的进程退出同步块(synchronized block)。

您同步的对象不必实际用于 synchronized block 的任何部分;它可以是一个简单的互斥对象,其唯一目的是在同步块(synchronized block)中锁定和解锁。然而,重要的是要注意,简单地同步一个对象不会阻止其他线程修改它如果它们不同步该对象。它是程序员/约定强制锁,而不是内置锁,使用共享对象的所有代码都必须“同意”在其上同步。

例如,对于您上面编写的代码,即使您的 xyz() 方法在 cars 上同步,您也可以像这样编写另一个方法:

public void changeCar() {
    Car myCar = cars.get("abc");
    myCar.setColor("Blue");
}

修改 cars 而不调用 synchronized。此方法有可能在您的方法 xyz() 修改它的同时修改“abc”汽车(即违反线程安全),因为它不包含任何调用 synchronizedcars 上。

如果你想确保你的 cars map 是线程安全的(即永远不会同时被两种方法修改),你必须要么

  1. 确保任何修改 cars 的代码首先调用 synchronized(cars)
  2. 使用 ConcurrentHashMap ,这保证了对它的放置和获取操作是线程安全的。

关于java - 在静态变量中使用同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11623326/

相关文章:

.net - .NET 4.0线程池中有哪些改进?

multithreading - 潜在线程密集型应用程序中多个套接字的异步与同步套接字

python - 创建新实例时,python中的类变量是否会再次声明?

java - 需要一种缩放字体以适合矩形的方法

java - 如何将 facebook 登录与 Struts2 集成?

java - 如何使用 Java 验证 Azure B2C ID token 的 JWT 签名?

java - 替换 GlobalSettings.onStart 和 onStop

java - ResponseListener 在 snmp4j 中的工作原理

c# - C# 中具有复杂初始化的静态字符串变量

asp.net - ASP.NET页面中的静态变量