由不同类的线程更新的值不反映在java中的另一个类中

由不同类的线程更新的值不反映在java中的另一个类中,java,multithreading,Java,Multithreading,我编辑了我的问题,使之非常简单。 首先,在同一个文件中有两个类 HashMapClass:它创建ConccurentHashMap的实例 及 NewThread:更新hashMap的 public class HashMapClass { public static volatile ConcurrentHashMap serverMap = new ConcurrentHashMap(); public static void main(String args[]) { NewT

我编辑了我的问题,使之非常简单。 首先,在同一个文件中有两个类 HashMapClass:它创建ConccurentHashMap的实例 及 NewThread:更新hashMap的

public class HashMapClass {

public static volatile ConcurrentHashMap serverMap = new ConcurrentHashMap();

public static void main(String args[]) {

    NewThread nt = new NewThread();
    nt.start();
}
}

class NewThread extends Thread {

@Override
public void run() {
    HashMapClass.serverMap.put("Ishan", new Integer(3));

System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
  try {
        Thread.sleep(10000);
    } catch (InterruptedException ex) {
        Logger.getLogger(NewThread.class.getName()).log(Level.SEVERE, null, ex);
    }
    }
}
现在,它显示hashMap不是空的,但是如果我尝试从其他类New class访问它,它会显示为空

public class NewClass {

public static void main(String s[]) {
    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
    Set setMap = HashMapClass.serverMap.entrySet();
    Iterator i = setMap.iterator();
    for (int f = 0; i.hasNext(); ++f) {
        Map.Entry me = (Map.Entry) i.next();
        System.out.println("key is" + me.getKey() + "value is :" + me.getValue());
    }
}
}

此类永远不会使用数据更新。
我希望这现在很容易理解。

HashMap不是线程安全的,因此如果需要跨线程共享HashMap,则需要引入某种形式的同步

或者,更简单地说,使用

作为另一方,您可能会从阅读中受益,尤其是上一部分

编辑

在您的评论之后,请看一个简单的示例,我认为它可以解决您的问题—我的机器上的输出是:

哈希映射在main中为空(第一次尝试)?正确
哈希映射在运行中是否为空?假
哈希映射在main中为空(第二次尝试)?假的

第二次编辑

您可以从另一个类应用相同的逻辑-只需确保调用NewThread.start并等待足够的时间(或者直接调用NewThread.run,以便它在同一个线程中运行,而不必等待):


HashMap不是线程安全的,因此如果需要跨线程共享HashMap,则需要引入某种形式的同步

或者,更简单地说,使用

作为另一方,您可能会从阅读中受益,尤其是上一部分

编辑

在您的评论之后,请看一个简单的示例,我认为它可以解决您的问题—我的机器上的输出是:

哈希映射在main中为空(第一次尝试)?正确
哈希映射在运行中是否为空?假
哈希映射在main中为空(第二次尝试)?假的

第二次编辑

您可以从另一个类应用相同的逻辑-只需确保调用NewThread.start并等待足够的时间(或者直接调用NewThread.run,以便它在同一个线程中运行,而不必等待):


HashMap需要在其同步部分进行处理,因为它缺乏线程安全性

ConcurrentHashMap更擅长并发,ConcurrentHashMap在读取时不会锁定映射,在写入时也不会锁定整个映射。它将锁定当前正在绘制的地图部分

但需要注意的是,如果ConcurrentHashMap在迭代过程中发生更改,ConcurrentHashMap不会抛出ConcurrentModificationException

编辑的代码:

问题是HashMapClass和NewClass的执行,当JVM关闭时,在HashMapClass完成执行后,我们如何运行NewClass类并尝试检索存储在ConcurrentHashMap中的值,该值存储在堆上,一旦JVM终止,该值就会丢失。是的,因为ConcurrentHashMap标记为静态,所以该值存储在堆的内存区域中

public class HashMapClass {

public static  ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();

public static void main(String args[]) {

    NewThread nt = new NewThread();
    nt.start();
    try {
        nt.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    new NewClass().go();

  }
}

class NewThread extends Thread {


@Override
public void run() {

    HashMapClass.serverMap.put("Ishan", 3);

    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());



    }
}

 class NewClass {

public void go() {
    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
    for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){

       System.out.println(m.getKey()+" "+m.getValue());
  }

}
}
公共类HashMapClass{
公共静态ConcurrentHashMap服务器映射=新ConcurrentHashMap();
公共静态void main(字符串参数[]){
NewThread nt=新的NewThread();
nt.start();
试一试{
nt.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新建NewClass().go();
}
}
类NewThread扩展线程{
@凌驾
公开募捐{
HashMapClass.serverMap.put(“Ishan”,3);
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
}
}
类NewClass{
公开作废go(){
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
对于(Map.Entry m:HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+“”+m.getValue());
}
}
}

HashMap需要在其同步部分进行处理,因为它缺乏线程安全性

ConcurrentHashMap更擅长并发,ConcurrentHashMap在读取时不会锁定映射,在写入时也不会锁定整个映射。它将锁定当前正在绘制的地图部分

但需要注意的是,如果ConcurrentHashMap在迭代过程中发生更改,ConcurrentHashMap不会抛出ConcurrentModificationException

编辑的代码:

问题是HashMapClass和NewClass的执行,当JVM关闭时,在HashMapClass完成执行后,我们如何运行NewClass类并尝试检索存储在ConcurrentHashMap中的值,该值存储在堆上,一旦JVM终止,该值就会丢失。是的,因为ConcurrentHashMap标记为静态,所以该值存储在堆的内存区域中

public class HashMapClass {

public static  ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();

public static void main(String args[]) {

    NewThread nt = new NewThread();
    nt.start();
    try {
        nt.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    new NewClass().go();

  }
}

class NewThread extends Thread {


@Override
public void run() {

    HashMapClass.serverMap.put("Ishan", 3);

    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());



    }
}

 class NewClass {

public void go() {
    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
    for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){

       System.out.println(m.getKey()+" "+m.getValue());
  }

}
}
公共类HashMapClass{
公共静态ConcurrentHashMap服务器映射=新ConcurrentHashMap();
公共静态void main(字符串参数[]){
NewThread nt=新的NewThread();
nt.start();
试一试{
nt.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新建NewClass().go();
}
}
类NewThread扩展线程{
@凌驾
公开募捐{
HashMapClass.serverMap.put(“Ishan”,3);
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
}
}
类NewClass{
公开作废go(){
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
对于(Map.Entry m:HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+“”+m.getValue());
}
}
}

指出HashMap不是线程安全的。阅读建议。不要在线程之间共享它。一个快速的解决方法是使用一个。你不能通过反复试验,在你的代码周围撒上“volatile”和“synchronized”,就像在牛排上撒盐一样,让同步正常工作。你必须设计正确。没有别的办法。
public class HashMapClass {

public static  ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();

public static void main(String args[]) {

    NewThread nt = new NewThread();
    nt.start();
    try {
        nt.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    new NewClass().go();

  }
}

class NewThread extends Thread {


@Override
public void run() {

    HashMapClass.serverMap.put("Ishan", 3);

    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());



    }
}

 class NewClass {

public void go() {
    System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
    for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){

       System.out.println(m.getKey()+" "+m.getValue());
  }

}
}