【问题标题】:How to populate Map using the multiple classes using the thread safety approach [duplicate]如何使用线程安全方法使用多个类填充 Map [重复]
【发布时间】:2021-09-25 08:29:04
【问题描述】:

也许这个问题有答案,但根据我的搜索词找不到最适合我的东西,所以在这里发布问题。这个问题可能看起来很愚蠢,但这对我来说是新事物。请提供一些建议或解决方法。

我有一个Populator 类,它有一个Map。我希望在代码执行期间使用各种值填充此映射,然后最后我想获取 Map 中的所有值,然后根据我的要求进一步处理它。

到目前为止,我正在使用Static method and variable 来实现这一点。到目前为止,这似乎工作正常。但是我的导师告诉我,在并行处理多个请求时,这不会是线程安全的。我想知道如何使下面的代码线程安全。

为了更好的理解,我会用代码解释:

以下是我的Populcator.class,它将用于在代码处理期间填充Map,我在最后访问以进行进一步处理。我又创建了一个类 AnotherPopulator 作为解决此问题的方法,但它不能满足我的需要:

public class Populator {

    @Getter
    private static final HashMap<String,String> namespaces = new HashMap<>();

    public static void namespacePopulator(String key,String value){
        namespaces.put(key,value);
    }
}

@NoArgsConstructor
@Getter
class AnotherPopulator {

    private final HashMap<String,String> namespaces = new HashMap<>();

    public void namespacePopulator(String key,String value){
        this.namespaces.put(key,value);
    }
}

以下是A and B 类,在代码执行期间将调用我的Main.class 来填充Map

public class A {

    public void populatorA() {
        Populator.namespacePopulator("KeyA", "ValueA");
    }

    public void anotherPopulatorA(){
        AnotherPopulator anotherPopulator = new AnotherPopulator();
        anotherPopulator.namespacePopulator("KeyAA","ValueA1");
    }
}

public class B {
    public void populatorB() {
        Populator.namespacePopulator("KeyB", "ValueB");
    }

    public void anotherPopulatorB(){
        AnotherPopulator anotherPopulator = new AnotherPopulator();
        anotherPopulator.namespacePopulator("KeyB1","ValueB1");
    }
}

以下是我的Main.class,它将调用AB,然后最终获得Map,并在执行期间填充了所有值:

public class Main {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();

        a.populatorA();
        b.populatorB();

        //This will provide me with desired result but does not provide the thread safety
        System.out.println(Populator.getNamespaces());

        System.out.println("****************************");

        //This will provide thread safety but does not provide the desired result I would want as new object will be created at every stage
        AnotherPopulator anotherPopulator = new AnotherPopulator();
        System.out.println(anotherPopulator.getNamespaces());

        //I would like to populate a Map present in class from various classes during the execution then finally I would like to obtain all the values that were added during the
        // execution but want to do this using the thread safety approach
        
    }
}

以下是我得到的输出。第一部分具有我需要的值,但它不是线程安全的方法。第二部分没有我需要的值,但我相信这是一种线程安全的方法。

{KeyB=ValueB, KeyA=ValueA}
****************************
{}

我想知道如何使用Thread-safety 方法声明Map 并在整个代码执行生命周期中填充它,然后最终一起获取所有值。

我希望我能够清楚地解释这个问题。任何帮助/解决方法/建议都会对我很有帮助。提前致谢。

【问题讨论】:

    标签: java multithreading collections static thread-safety


    【解决方案1】:

    正如评论中提到的使用ConcurrentHashMap

    public class Populator {
    
        @Getter
        private static final ConcurrentHashMap<String,String> namespaces = new ConcurrentHashMap <>();
    
        public static void namespacePopulator(String key,String value){
            namespaces.putIfAbsent(key,value);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-13
      • 2014-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多