简体   繁体   English

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

[英]Thread issue while using Executor service

I have facing thread issue in the below code.When then thread executes the Run method of the runnable object,it doesnt print the data that I expect it to be. 我在下面的代码中遇到了线程问题。当线程执行可运行对象的Run方法时,它不会打印我期望的数据。

code 1--calling code 代码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);

In the above code,I have checked that logData Returned by the CPEMethodData.getLogDataMap()is different which I expected.But still when the runnable object actually executes,it runs with same data... 在上面的代码中,我检查了CPEMethodData.getLogDataMap()返回的logData是否与我期望的不同。但是仍然在可运行对象实际执行时,它使用相同的数据运行...

code 2--creating thread pool with 5 threads... 代码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);     
    }

Code 3--runnable code 代码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;
        }
    }

Below is the CPEmethoddata.getLogData 以下是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;
}

}

when I run the code 1 which submits two runnable to the queue,I expect to see different logData content in the sysout of the run method but as i have debugged it I see that data is same in both the executions...seems that 2nd runnable is interfering with the first one....Can anyone please help me to understand what is the problem here.I thought I am passing 2 different instances of CatalogLogger and shouldnt cause any problem..Also can anyone please suggest any solution for this ? 当我运行将两个可运行的提交到队列的代码1时,我希望在run方法的sysout中看到不同的logData内容,但是正如我调试的那样,我看到两个执行中的数据都是相同的...似乎第二个runnable正在干扰第一个。.有人可以帮助我了解这里的问题吗。我以为我正在传递2个不同的CatalogLogger实例,应该不会引起任何问题..也有人可以建议对此提出任何解决方案?

As written by the @ReneLink in the comment to my question ,CPEMethodData.getLogDataMap was returning same instance of the hashmap...So by the time thread's run method was getting executed hashmap's content were getting modified.I created deep copy of the hashmap using Cloner facility and passed the same to the thread. 正如@ReneLink在对我的问题的评论中所写的那样,CPEMethodData.getLogDataMap返回的是哈希表的相同实例...因此,在执行线程的run方法时,哈希表的内容被修改了。我使用以下方法创建了哈希表的深层副本克隆工具并将其传递给线程。 Thanks @ReneLink for pointing out this to me. 感谢@ReneLink向我指出这一点。

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

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