gpt4 book ai didi

java - 使用单独的线程更新全局 HashMap 时出现空指针异常

转载 作者:行者123 更新时间:2023-11-30 06:05:47 25 4
gpt4 key购买 nike

我在 Hashmap 中遇到空指针异常,它是一个全局变量,并且由单独的线程进行更新。在调试时,所有线程都运行良好并更新 HashMap ,但是当我执行程序时,一个线程抛出空指针。

public class RunEngine {

/**
* @param args
*/

public static Map<Integer, List<Event>> queue_map = new HashMap<Integer, List<Event>>();

public static void main(String[] args) {


/*
* check file present in data set folder or not , if present fetch the file name
* and store then in a list
*/
File folder = new File(ConfigurationParameters.FOLDER_PATH);
File[] listOfFiles = folder.listFiles();

/* Create a thread pool for number of Publishers which you want to initialise */
ThreadPoolExecutor executor = new ThreadPoolExecutor(ConfigurationParameters.P_NUMBER,
ConfigurationParameters.P_NUMBER + 3, 100, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy()); // P_NUMBER = 2

for (int i = 1; i <= ConfigurationParameters.P_NUMBER; i++) {

ConnectP conn = new ConnectP(
ConfigurationParameters.FOLDER_PATH + "\\" + listOfFiles[i - 1].getName(),
ConfigurationParameters.DISTRIBUTION_RANDOM, i);
executor.execute(conn);
}
executor.shutdown();



}

}

ConnectP 类如下所示:

public class ConnectP implements Runnable {

private String file_path;
private String distribution_constant;
private int pub_id;

/**
* @param file_path
* @param distribution_constant
*/
public ConnectP(String file_path, String distribution_constant, int pub_id) {
super();
this.file_path = file_path;
this.distribution_constant = distribution_constant;
this.pub_id = pub_id;
}

public void streamevent(List<Event> eventlist, String distributionconstant)
throws InterruptedException {


if (distributionconstant.matches(ConfigurationParameters.PUBLISHER_DISTRIBUTION_RANDOM)) {

List<Event> publisherqueue = new ArrayList<>();
RunEngine.queue_map.put(pub_id, publisherqueue);
for (Event event : eventlist) {
long start = System.currentTimeMillis(); // get present system timestamp
event.setTimeStamp(start);
publisherqueue.add(event); // add to publisher queue
Random rand = new Random();
int value = rand.nextInt(1000); // add a random seed for streaming
Thread.sleep(value); // sleep the process for that value
System.out.println("Publisher " + String.valueOf(pub_id) + " : " + RunEngine.queue_map.get(pub_id).size()); **(throwing exception line 68)**


}

}


}
// function to connect to source file and return list of publication event
public List<Event> connectsource(String filepath) {
// return list after reading file
return list;
}


@Override
public void run() {
// TODO Auto-generated method stub

List<Event> event = this.connectsource(file_path); // connect to source
try {
System.out.println("THREAD " + String.valueOf(pub_id)+ " Initiated");
this.streamevent(event, distribution_constant);**(throwing exception line 121)**
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}

我得到的异常(exception)是

Exception in thread "pool-1-thread-1" java.lang.NullPointerException
at org.test.event.ConnectP.streamevent(ConnectP.java:68)
at org.test.event.ConnectP.run(ConnectP.java:121)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

我将感谢您的帮助。如果有一些有效的方法可以做到这一点,我们将不胜感激。

最佳答案

I am getting a Null pointer exception in my Hashmap which is a global variable and is getting updated by separate threads.

HashMap 不是同步类。如果多个线程同时更新映射,那么它们的该映射的内存 View 很可能会不同步,这可能会导致 NPE、无限循环或其他不好的事情。

最简单的方法是使用 ConcurrentHashMap 类来为您处理同步。

// thread-1   
RunEngine.queue_map.put(pub_id, publisherqueue);
...
// thread-2
RunEngine.queue_map.get(pub_id).size()

对。一个线程看起来正在放入,而另一个线程正在获取。当您在多个线程中执行此操作时,您需要担心:

  • 内存可见性,以确保一个线程中对 map 的更改可以被其他线程看到。
  • 锁定以确保两个线程不会同时对 map 进行更改以及它们的更新发生冲突。

基本上每个线程都有一个每个处理器的本地内存缓存,允许它有效地访问缓存的结果,而不必从主内存获取所有内容。因此,当线程 1 更新映射时,它只能在其缓存中执行此操作。如果线程 2 然后从映射中获取,它可能看不到任何更新,或者更糟糕的是,根据虚拟内存详细信息,映射的部分更新。如果两个线程都在更新映射,则将其内存缓存刷新到主内存的线程将覆盖另一个线程所做的更新。

对于您在线程之间共享的任何对象都是如此。只有具有最终字段的不可变对象(immutable对象)才可以在线程之间共享而无需担心。否则,您需要使用 volatilesynchronized 关键字来确保它们正确共享。要正确地做到这一点相当困难,并且需要丰富的 Java 线程和内存同步结构经验。

Java tutorial about synchronization可能是一个很好的起点。

关于java - 使用单独的线程更新全局 HashMap 时出现空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51378326/

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