【问题标题】:Set and Update concurrenthashmap from multiple thread从多个线程设置和更新并发哈希图
【发布时间】:2014-06-16 16:36:21
【问题描述】:

我正在使用 ConcurrentHashamp 实现客户端查找映射。

    private ConcurrentHashMap<String,SignupDTO> map = new <String,SignupDTO> ConcurrentHashMap();*
    public  SignupDTO get(String opcode) 
    {
      return this.map.get(opcode);
    }
    public  void set(String opcode,SignupDTO dto) 
    {
      this.map.put(opcode, dto);
    }

这里从多个线程调用get和set函数来更新和获取客户端信息。 我有另一个函数 update(),它在特定时间后从特定线程调用,并使用更新的客户端信息更新地图。

public  void update() 
    {
        Connection connection = null;
        Statement stmt = null;
        ResultSet rs = null;

        try 
        {
            connection = DatabaseManager.getInstance().getConnection();
            stmt = connection.createStatement();    
            String sql= "select * from client";
            rs = stmt.executeQuery(sql);
            while (rs.next()) 
            {
                SignupDTO row = new SignupDTO();
                ......
                            ..........
                this.map.put(key, row);         
            }

        } 
    }

map 上的 get 和 set 操作是否是线程安全的?请帮帮我。

【问题讨论】:

  • 我的意思是地图上的get和set操作是否是线程安全的。
  • @nosid 我的意思是地图上的获取和设置操作是否是线程安全的。
  • @nosid 无法理解“但是,方法更新中的各个操作在整个方法完成之前是可见的。”
  • 假设地图最初包含"foo"=1"bar"=2。方法update 从数据库中读取"foo"=3"bar"=4 并执行更新。然后另一个线程可能会读取"foo"=3,然后是"bar"=2。这基本上是可能发生的最糟糕的事情。
  • @nosid 我明白了。我怎样才能避免这种情况?

标签: java multithreading thread-safety concurrenthashmap


【解决方案1】:

正如@nosid 指出的那样,您的update 方法将不是线程安全的(= 它只能更新地图的一半,然后有人可以读取旧/新值的混合,您的更新方法将完成另一个更新一半)。

我建议您将查询结果放入 Map(不是并发的),并使用 ConcurrentHashMap 中的 putAll 方法进行更新,这是线程安全的(或至少 official documentation 如此)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 2013-10-18
    • 2013-03-30
    • 2018-02-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多