繁体   English   中英

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

[英]Thread issue while using Executor service

我在下面的代码中遇到了线程问题。当线程执行可运行对象的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内容,但是正如我调试的那样,我看到两个执行中的数据都是相同的...似乎第二个runnable正在干扰第一个。.有人可以帮助我了解这里的问题吗。我以为我正在传递2个不同的CatalogLogger实例,应该不会引起任何问题..也有人可以建议对此提出任何解决方案?

正如@ReneLink在对我的问题的评论中所写的那样,CPEMethodData.getLogDataMap返回的是哈希表的相同实例...因此,在执行线程的run方法时,哈希表的内容被修改了。我使用以下方法创建了哈希表的深层副本克隆工具并将其传递给线程。 感谢@ReneLink向我指出这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM