如何在不返回实例或使用 Java 中使用的数据副本的情况下访问属性?
How to gain access to an attribute without returning an instance or copy of the data using in Java?
我正在编写一个多线程程序,我需要获得对 Map 的访问权限,但我不知道如何确保多个线程不会修改 Map。我想知道是否有一种方法可以创建同步的方法,并且 returns class 中的 Map 当程序对其进行更改时,它会反映在主要属性中。
下面是给我一个 ConcurrentModificationException 的代码。这是因为两个线程是
同时访问地图?错误发生在 remove 方法中。我还包含了 notify 方法,因为该方法每隔几分钟就会被调用一次,我想知道这个错误是否与被调用的方法有关。
***我的 notifyObserver 方法仍然缺少一些逻辑,因此更改的属性始终为真。
private static final Map<WeatherDotComLocation, List<Observer>> locationAndObserver = new ConcurrentHashMap<>();
public void remove(Observer o) {
killThread(o);
Set<WeatherDotComLocation> weatherLocations = locationAndObserver.keySet();
for(WeatherDotComLocation location : weatherLocations) {
List<Observer> observerListToCheck = locationAndObserver.get(location);
for(Observer suspectObserver : observerListToCheck) {
if(suspectObserver.equals(o)) {
observerListToCheck.remove(o);
}
}
if(observerListToCheck.size() == 0) {
locationAndObserver.remove(location);
}
}
}
public void notifyObservers() {
Set<WeatherDotComLocation> keySet = locationAndObserver.keySet();
for (WeatherDotComLocation location : keySet) {
Thread thread = new Thread(() -> {
WeatherManager weatherManager = new WeatherManager();
boolean changed = true;
if(changed) {
List<WeatherDotComForecast> weatherForecast = weatherManager.pullData(location, 5);
for(Observer observer : locationAndObserver.get(location)) {
observer.update(weatherForecast);
}
}
});
thread.start();
}
}
synchronized
只保护同步内的块。如果您 return 一个集合到一个未受保护的区域,则可以在 read/written 块外时更改此地图。
我怀疑最简单的选择是使用线程安全集合,例如
private final Map<String, MyType> map = Collections.synchronizedMap(new HashMap<>());
或
private final Map<String, MyType> map = new ConcurrentHashMap<>();
这些可以以线程安全的方式使用,而不需要使用 synchronized
这样一来,你只有一个对象实例,你的线程可以通过Object object = AClass.getInstance();
:
来访问它
public class AClass
{
private static Object instance;
public static synchronized Object getInstance() {
if (instance == null)
instance = new Object();
return instance;
}
}
AClass
还可以定义其他修改对象状态的方法。
我正在编写一个多线程程序,我需要获得对 Map 的访问权限,但我不知道如何确保多个线程不会修改 Map。我想知道是否有一种方法可以创建同步的方法,并且 returns class 中的 Map 当程序对其进行更改时,它会反映在主要属性中。
下面是给我一个 ConcurrentModificationException 的代码。这是因为两个线程是 同时访问地图?错误发生在 remove 方法中。我还包含了 notify 方法,因为该方法每隔几分钟就会被调用一次,我想知道这个错误是否与被调用的方法有关。
***我的 notifyObserver 方法仍然缺少一些逻辑,因此更改的属性始终为真。
private static final Map<WeatherDotComLocation, List<Observer>> locationAndObserver = new ConcurrentHashMap<>();
public void remove(Observer o) {
killThread(o);
Set<WeatherDotComLocation> weatherLocations = locationAndObserver.keySet();
for(WeatherDotComLocation location : weatherLocations) {
List<Observer> observerListToCheck = locationAndObserver.get(location);
for(Observer suspectObserver : observerListToCheck) {
if(suspectObserver.equals(o)) {
observerListToCheck.remove(o);
}
}
if(observerListToCheck.size() == 0) {
locationAndObserver.remove(location);
}
}
}
public void notifyObservers() {
Set<WeatherDotComLocation> keySet = locationAndObserver.keySet();
for (WeatherDotComLocation location : keySet) {
Thread thread = new Thread(() -> {
WeatherManager weatherManager = new WeatherManager();
boolean changed = true;
if(changed) {
List<WeatherDotComForecast> weatherForecast = weatherManager.pullData(location, 5);
for(Observer observer : locationAndObserver.get(location)) {
observer.update(weatherForecast);
}
}
});
thread.start();
}
}
synchronized
只保护同步内的块。如果您 return 一个集合到一个未受保护的区域,则可以在 read/written 块外时更改此地图。
我怀疑最简单的选择是使用线程安全集合,例如
private final Map<String, MyType> map = Collections.synchronizedMap(new HashMap<>());
或
private final Map<String, MyType> map = new ConcurrentHashMap<>();
这些可以以线程安全的方式使用,而不需要使用 synchronized
这样一来,你只有一个对象实例,你的线程可以通过Object object = AClass.getInstance();
:
public class AClass
{
private static Object instance;
public static synchronized Object getInstance() {
if (instance == null)
instance = new Object();
return instance;
}
}
AClass
还可以定义其他修改对象状态的方法。