我有一个静态 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”汽车(即违反线程安全),因为它不包含任何调用 synchronized
在 cars
上。
如果你想确保你的 cars
map 是线程安全的(即永远不会同时被两种方法修改),你必须要么
- 确保任何修改
cars
的代码首先调用synchronized(cars)
- 使用 ConcurrentHashMap ,这保证了对它的放置和获取操作是线程安全的。
关于java - 在静态变量中使用同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11623326/