gpt4 book ai didi

java - 使用 Executor 服务时出现线程问题

转载 作者:行者123 更新时间:2023-12-01 04:36:57 24 4
gpt4 key购买 nike

我在下面的代码中遇到了线程问题。当线程执行可运行对象的 Run 方法时,它不会打印我期望的数据。

代码1--调用代码

Map<String,Object> logData = CPEMethodData.getLogDataMap();
CatalogUpdaterLogger.getLogger().info("6 before new splunk logger log data =" + logData);
CatalogrLogger writer = new CatalogLogger(LogType.INFO,logData,LoggerType.CATALOGUPDATER);
LogPool.INSTANCE.submitTask(writer);//submitting writer which is a runnable object to the queue

//add one more task/writer to the queue in the same method

logData = CPEMethodData.getLogDataMap();
CatalogUpdaterLogger.getLogger().info("11 before 3rd writer=logData "+logData);
CatalogLogger writer2 = new CatalogLogger(LogType.INFO,logData,LoggerType.CATALOGUPDATER);

LogPool.INSTANCE.submitTask(writer2);

在上面的代码中,我检查了 CPEMethodData.getLogDataMap() 返回的 logData 与我预期的不同。但是当可运行对象实际执行时,它仍然以相同的数据运行...

代码2--创建5个线程的线程池...

public enum LogPool {

INSTANCE;
private static final int nThreads = 5;
final ExecutorService executor = Executors.newFixedThreadPool(nThreads);

public synchronized void submitTask(Runnable task) {
executor.execute(task);
}

代码3--可运行代码

public class CatalogLogger implements Runnable {
protected LogType logType;
protected LoggerType loggerType;
protected Map<String, Object> logData;
public CatalogLogger(LogType logType, Map<String, Object> logData,
LoggerType loggerType) {
this.logType = logType;
this.logData = logData;
this.loggerType = loggerType;
}

public void run() {
System.out.println("running with logData " + logData);
System.out.println(" Thread.currentThread().hashCode() " +Thread.currentThread().hashCode());
switch (loggerType) {
case ORDERPROCESSING:
logData(Logger.getLogger(ORDER_LOG));
break;
case CATALOGUPDATER:
logData(Logger.getLogger(CATALOGUPDATER_LOG));
break;
}
}

下面是CPEmethoddata.getLogData

public class CPEMethodData {
private static ThreadLocal<Map<String, Object>> logDataMap = new ThreadLocal<Map<String, Object>>();

public static Map<String,Object> getLogDataMap() {
return logDataMap.get();
}
public static void setOppParameters(Map<String, Object> inputParams) {
Map<String, Object> oppStatus = logDataMap.get();
if (oppStatus == null) {
oppStatus = new HashMap<String, Object>();
logDataMap.set(oppStatus);
}
oppStatus.put(INPUT_PARAMS, inputParams);
}

@SuppressWarnings("unchecked")
public static Map<String, Object> getOperationParameters() {
Map<String, Object> oppStatus = logDataMap.get();
if (oppStatus != null)
return (Map<String, Object>) oppStatus.get(INPUT_PARAMS);
return null;
}

}

当我运行向队列提交两个可运行对象的代码 1 时,我希望在 run 方法的 sysout 中看到不同的 logData 内容,但当我对其进行调试时,我发现两次执行中的数据是相同的...似乎第二个可运行对象正在干扰第一个......任何人都可以帮助我理解这里的问题是什么。我想我正在传递 CatalogLogger 的 2 个不同实例,并且不应该引起任何问题。.也有人可以建议任何解决这个问题?

最佳答案

正如 @ReneLink 在对我的问题的评论中所写的那样,CPEMethodData.getLogDataMap 返回了 hashmap 的相同实例...因此,当线程的 run 方法被执行时,hashmap 的内容正在被修改。我创建了深拷贝使用 Cloner 工具创建 HashMap 并将其传递给线程。感谢@ReneLink 向我指出这一点。

关于java - 使用 Executor 服务时出现线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17205069/

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