使用单独的线程更新全局哈希映射时出现Nullpointer异常



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

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 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)

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

我在Hashmap中得到一个Null指针异常,它是一个全局变量,由单独的线程更新。

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

<tldr>要做到这一点,最简单的方法是使用ConcurrentHashMap类,它为您负责同步<tldr>

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

对。一个线程看起来正在投入,另一个线程正在获取。当你在多个线程中这样做时,你需要担心:

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

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

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

关于同步的Java教程可能是入门的好地方。

您可以使用并发HashMap实现线程安全。

相关内容

  • 没有找到相关文章

最新更新