【发布时间】:2014-04-28 19:07:37
【问题描述】:
我正在尝试实现锁定,我不希望在写入时发生读取。
下面是我使用CountDownLatch 的ClientData 类-
public class ClientData {
private static final AtomicReference<Map<String, Map<Integer, String>>> primaryMapping = new AtomicReference<>();
private static final AtomicReference<Map<String, Map<Integer, String>>> secondaryMapping = new AtomicReference<>();
private static final AtomicReference<Map<String, Map<Integer, String>>> tertiaryMapping = new AtomicReference<>();
// should this be initialized as 1?
private static final CountDownLatch hasBeenInitialized = new CountDownLatch(1)
public static Map<String, Map<Integer, String>> getPrimaryMapping() {
try {
hasBeenInitialized.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return primaryMapping.get();
}
public static void setPrimaryMapping(Map<String, Map<Integer, String>> map) {
primaryMapping.set(map);
hasBeenInitialized.countDown();
}
public static Map<String, Map<Integer, String>> getSecondaryMapping() {
try {
hasBeenInitialized.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return secondaryMapping.get();
}
public static void setSecondaryMapping(Map<String, Map<Integer, String>> map) {
secondaryMapping.set(map);
hasBeenInitialized.countDown();
}
public static Map<String, Map<Integer, String>> getTertiaryMapping() {
try {
hasBeenInitialized.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return tertiaryMapping.get();
}
public static void setTertiaryMapping(Map<String, Map<Integer, String>> map) {
tertiaryMapping.set(map);
hasBeenInitialized.countDown();
}
}
问题陈述:-
我需要等待上面代码中的三个AtomicReferences 的get 调用。一旦对我的三个 AtomicReferences 和 set 调用完成了所有写入,那么我将允许调用我拥有的三个 getter。
所以我决定使用CountDownLatch,我已经初始化为1?我需要将其初始化为3吗?并且每次在我对新更新进行第一次设置之前,我是否需要将倒计时闩锁重新设置回 3?因为我将在单独的三个语句中设置这三个 AtomicReferences。
我猜我上面的代码有问题?
注意:-
我将在其他班级进行这样的设置 -
ClientData.setPrimaryMapping(primaryTables);
ClientData.setSecondaryMapping(secondaryTables);
ClientData.setTertiaryMapping(tertiaryTables);
一旦设置了这些AtomicReferences,其他一些线程必须从这些AtomicReferences中读取数据。
更新:-
下面是我的后台线程代码,它将从 URL 中获取数据,对其进行解析并将其存储在 ClientDataclass 变量中。
public class TempScheduler {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void startScheduler() {
final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
callServers();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 0, 10, TimeUnit.MINUTES);
}
}
// call the servers and get the data and then parse
// the response.
private void callServers() {
String url = "url";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
parseResponse(response);
}
// parse the response and store it in a variable
private void parseResponse(String response) {
//...
ConcurrentHashMap<String, Map<Integer, String>> primaryTables = null;
ConcurrentHashMap<String, Map<Integer, String>> secondaryTables = null;
ConcurrentHashMap<String, Map<Integer, String>> tertiaryTables = null;
//...
// store the data in ClientData class variables which can be
// used by other threads
ClientData.setPrimaryMapping(primaryTables);
ClientData.setSecondaryMapping(secondaryTables);
ClientData.setTertiaryMapping(tertiaryTables);
}
}
【问题讨论】:
-
在这里使用
synchronized关键字不是更容易更易读吗? -
请张贴入口点方法的代码
main。 -
你考虑过
ReadWriteLock吗?这正是它的设计目的。 -
如果
ClientData.setPrimaryMapping(primaryTables);同时被调用3次呢? -
@Braj:肯定不会同时调用 3 次。我已经更新了设置这三个 AtomicReference 的代码。
标签: java multithreading countdownlatch atomicreference