gpt4 book ai didi

java - HashMap 更新未反射(reflect)在线程之间

转载 作者:行者123 更新时间:2023-11-29 05:52:38 25 4
gpt4 key购买 nike

我有一个包含 hahsmap 的单例类,hashmap 被初始化为类变量。该 map 已正确更新,因为当我添加和打印它的大小时,它发生了变化,但是,当我从不同的线程调用它时, map 始终为空。发生这种情况是否有特殊原因?

如果这有任何区别,我正在使用 ConccurentHashMap。

谢谢

Singleton decleration:

public class ClientRegistryDetailsSingleton {

private static ClientRegistryDetailsSingleton instance = null;
private ConcurrentHashMap<String, Integer> tickerToNumberRegistered = new ConcurrentHashMap<String,Integer>();


protected ClientRegistryDetailsSingleton() {
// Exists only to defeat instantiation.
}

public static ClientRegistryDetailsSingleton getInstance() {
if(instance == null) {
instance = new ClientRegistryDetailsSingleton();
}
return instance;
}

public void setTickerToNumberRegistered(ConcurrentHashMap<String, Integer> tickerToNumberRegistered) {
this.tickerToNumberRegistered = tickerToNumberRegistered;
}

public ConcurrentHashMap<String, Integer> getTickerToNumberRegistered() {
return tickerToNumberRegistered;
}


public void addToClienets(String ticker){}

public void removeFromClients(String ticker){}
}

从另一个线程调用它:

String[] splitForTicker = message.split(",");

ConcurrentHashMap<String, Integer> map = ClientRegistryDetailsSingleton.getInstance().getTickerToNumberRegistered();
System.out.println("The number of items in the map from senders persepctive" + map.size());

输出:

The number of items in the map from senders persepctive 0
2012-11-12 14:29:12,495 [Process messages received] INFO com.feed.feedReceive.ProcessFeedStreamLine - Successfully received a message from the feed
The number of items in the map from senders persepctive 0
1 :the size of the map now someone has added
2012-11-12 14:29:15,495 [Process messages received] INFO com.feed.feedReceive.ProcessFeedStreamLine - Successfully received a

message from the feed The number of items in the map from senders persepctive 0

Singleton 的新代码

public class ClientRegistryDetailsSingleton {

private static ClientRegistryDetailsSingleton instance = new ClientRegistryDetailsSingleton();
private volatile ConcurrentHashMap<String, Integer> tickerToNumberRegistered = new ConcurrentHashMap<String,Integer>();

protected ClientRegistryDetailsSingleton() {
// Exists only to defeat instantiation.
}

public static synchronized ClientRegistryDetailsSingleton getInstance() {
return instance;
}

public synchronized ConcurrentHashMap<String, Integer> getTickerToNumberRegistered() {
return tickerToNumberRegistered;
}

public void addToClienets(String ticker){}

public void removeFromClients(String ticker){}
}

最佳答案

发布的代码中存在竞争条件,如果两个线程调用 getInstance() 并且单例尚未构建,则可能导致构建多个单例实例:

public static ClientRegistryDetailsSingleton getInstance() {
if(instance == null) { // Line 1
instance = new ClientRegistryDetailsSingleton(); // Line 2
}
}

可能执行两个线程,T1T2:

  • T1 在第 1 行执行检查并进入 if 分支。
  • T1 已挂起,instance 仍为 null
  • T2 在第 1 行执行检查并进入 if 分支。
  • T2 构造类并分配给实例
  • T2 返回实例给调用者。
  • T2 暂停。
  • T1 再次启动并构造另一个实例并分配给instance

单实例的构造必须是线程安全的。可能的解决方案是:

  • 使 getInstance() 方法同步
  • 不要使用惰性初始化(如果可能):

    private static final ClientRegistryDetailsSingleton instance =
    new ClientRegistryDetailsSingleton();

关于java - HashMap 更新未反射(reflect)在线程之间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13345112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com