【问题标题】:java synchronized and shared tablesjava同步和共享表
【发布时间】:2015-01-25 02:38:19
【问题描述】:

我有一个包含表(哈希图)的单例对象(类)。所有其他对象(客户端)读取存储在表中的其他客户端列表。所有使用该表的方法都被同步关键字包围。我已经调试过表对于不同的客户有不同的值的情况。客户端可能在也可能不在同一个线程上运行,这就是我添加同步关键字的原因。

这里是使用 hashmap 的方法:

public synchronized Client addToConnectedClients(long key, Client client)
{
    return allConnectedClients.put(key, client);
}   

public synchronized Client getFromConnectedClients(long key)
{
    return allConnectedClients.get(key);
}

public synchronized Client removeFromConnectedClients(long key)
{
    return allConnectedClients.remove(key);
}

这是我从客户端对象内部访问表的方式:

Client temp=AppInterface.getInstance().getAppNetworkLogic().getFromConnectedClients(key);

AppNetowrkLogicAppInterface 单例中的一个对象,它是在创建 AppInterface 时。

我不知道这是怎么发生的。

编辑: 这是getInstance 方法:

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

【问题讨论】:

  • 你能显示 AppInterface.getInstance() 的代码吗?我怀疑那里有比赛条件。
  • 我猜这就是为什么当前的单例模式是一个枚举。

标签: java multithreading synchronized volatile


【解决方案1】:

正如我所怀疑的,在多个客户端访问 getInstance 的竞争条件下,可能会发生竞争条件,并且可以创建多个 AppInterface

要么急切地创建 AppInterface

private static AppInterface instance=new AppInterface();
public static AppInterface getInstance()
{
    return instance;        
}

或同步访问AppInterface

private static AppInterface instance=null;
public static AppInterface getInstance()
{
    synchronized(AppInterface.class) {
        if(instance == null)
        {
            instance= new AppInterface();
        }
    }
    return instance;        
}

【讨论】:

  • 我不确定这是否重要,但是当程序启动时,它会在主函数中创建AppInterface,然后才使用AppInterface。很多时间过去后也会出现问题。再次不确定这是否重要
  • @Maro 每次使用时请输出表格。如果结果不一致,可能与getInstance 方法有关。 @shazin 你的第二种方式不是线程安全的。请使用double-checked locking
  • @qqibrow 是的,我已经检查过了,但并不一致,但就像我说的 AppInterface 是在主函数中创建的,并且问题在很长一段时间后出现。通常,getInstance 方法的问题应该在 2 个不同的线程尝试初始化一个对象的开始出现,但如果它是在这些线程创建之前创建的,那么应该不会有问题吧?
  • @Maro 你能试试private static AppInterface instance=new AppInterface(); public static AppInterface getInstance() { return instance; } 问题还在吗?
  • @qqibrow 实际上,我现在像 dave 评论中的建议一样将单例设为枚举,但问题很难重现,因为这是具有真实客户端的实际服务器,并且问题在经过很长一段时间后才会出现时间
猜你喜欢
  • 2012-06-28
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
相关资源
最近更新 更多