Java 访问和更新在另一个线程的不同线程中创建的HasMap

Java 访问和更新在另一个线程的不同线程中创建的HasMap,java,multithreading,maven,testng,Java,Multithreading,Maven,Testng,我计划使用maven surefire插件并行执行2个自动化测试套件 当我执行下面提供的parallelSuiteTest.xml时,我面临一些问题。。。正在获取空哈希映射详细信息 在代码中,我所做的是在测试套件(Thread1)启动时初始化hashmap,即,executionDetailsMap 在testmethodstart(Thread2)上,我正在初始化另一个hashmap,即testMethodResultsMap,并向映射中添加一些数据。 现在在testMethod完成时,我将把

我计划使用maven surefire插件并行执行2个自动化测试套件

当我执行下面提供的parallelSuiteTest.xml时,我面临一些问题。。。正在获取空哈希映射详细信息

在代码中,我所做的是在测试套件(Thread1)启动时初始化hashmap,即,executionDetailsMap

在testmethodstart(Thread2)上,我正在初始化另一个hashmap,即testMethodResultsMap,并向映射中添加一些数据。 现在在testMethod完成时,我将把thread2的testMethodResultsMap数据放入在thread1中创建的executionDetailsMap

类似地,我对在(线程3)中执行的另一个testMethod也做了同样的操作

现在,在TestSuiteFinish方法中,当我尝试访问在onSuite start(Thread1)中创建的executionDetailsMap时,我得到的是空映射

你能告诉我我犯了什么错误以及如何在主线程(线程1)中获取插入的数据吗

ThreadTest.java

import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class ThreadTest {
    @BeforeTest
    public void beforeTestMethod() {
        System.out.println("before test");
    }

    @Test
    public void testMethod() {
        synchronized (Listener.testMethodResultsMap.get()) {
            Listener.testMethodResultsMap.get().put("firstKey", "FIrstValue");
        }
    }

    @AfterTest
    public void afterTestMetho() {
        System.out.println("after test method");
    }
}
import java.util.HashMap;
import java.util.LinkedHashMap;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class Listener implements ITestListener, ISuiteListener {
    public static ThreadLocal<HashMap<String, LinkedHashMap<String, String>>> executionDetailsMap = null;
    public static ThreadLocal<LinkedHashMap<String, String>> testMethodResultsMap = null;


    @Override
    public void onStart(ISuite suite) {
        System.out.println("===> On Suite Start");
        executionDetailsMap = new ThreadLocal<HashMap<String, LinkedHashMap<String, String>>>() {
            @Override
            protected HashMap<String, LinkedHashMap<String, String>> initialValue() {
                return new HashMap<String, LinkedHashMap<String, String>>();
            }
        };  
        System.out.println(executionDetailsMap);
    }

    @Override
    public void onFinish(ISuite suite) {
        System.out.println("==> On Suite Finish" + executionDetailsMap);
        System.out.println(executionDetailsMap.get());
        System.out.println("------" + Thread.currentThread().getId());
        System.out.println(testMethodResultsMap);
    }

    @Override
    public void onTestStart(ITestResult result) {

        System.out.println(Thread.currentThread().getId());
        if(null!=testMethodResultsMap){ 
            synchronized (testMethodResultsMap) { } 
        } else {
            testMethodResultsMap = new ThreadLocal<LinkedHashMap<String, String>>() {
                @Override
                protected LinkedHashMap<String, String> initialValue() {
                    return new LinkedHashMap<String, String>();
                }
            };
        }

    }

    @Override
    public void onTestSuccess(ITestResult result) {
        synchronized (executionDetailsMap) {
                executionDetailsMap.get().put(Thread.currentThread().getId() +"", testMethodResultsMap.get());
        }
    }

    @Override
    public void onTestFailure(ITestResult result) {}
    @Override
    public void onTestSkipped(ITestResult result) {}
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
    @Override
    public void onStart(ITestContext context) { }
    @Override
    public void onFinish(ITestContext context) { }
}
Listener.java

import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class ThreadTest {
    @BeforeTest
    public void beforeTestMethod() {
        System.out.println("before test");
    }

    @Test
    public void testMethod() {
        synchronized (Listener.testMethodResultsMap.get()) {
            Listener.testMethodResultsMap.get().put("firstKey", "FIrstValue");
        }
    }

    @AfterTest
    public void afterTestMetho() {
        System.out.println("after test method");
    }
}
import java.util.HashMap;
import java.util.LinkedHashMap;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class Listener implements ITestListener, ISuiteListener {
    public static ThreadLocal<HashMap<String, LinkedHashMap<String, String>>> executionDetailsMap = null;
    public static ThreadLocal<LinkedHashMap<String, String>> testMethodResultsMap = null;


    @Override
    public void onStart(ISuite suite) {
        System.out.println("===> On Suite Start");
        executionDetailsMap = new ThreadLocal<HashMap<String, LinkedHashMap<String, String>>>() {
            @Override
            protected HashMap<String, LinkedHashMap<String, String>> initialValue() {
                return new HashMap<String, LinkedHashMap<String, String>>();
            }
        };  
        System.out.println(executionDetailsMap);
    }

    @Override
    public void onFinish(ISuite suite) {
        System.out.println("==> On Suite Finish" + executionDetailsMap);
        System.out.println(executionDetailsMap.get());
        System.out.println("------" + Thread.currentThread().getId());
        System.out.println(testMethodResultsMap);
    }

    @Override
    public void onTestStart(ITestResult result) {

        System.out.println(Thread.currentThread().getId());
        if(null!=testMethodResultsMap){ 
            synchronized (testMethodResultsMap) { } 
        } else {
            testMethodResultsMap = new ThreadLocal<LinkedHashMap<String, String>>() {
                @Override
                protected LinkedHashMap<String, String> initialValue() {
                    return new LinkedHashMap<String, String>();
                }
            };
        }

    }

    @Override
    public void onTestSuccess(ITestResult result) {
        synchronized (executionDetailsMap) {
                executionDetailsMap.get().put(Thread.currentThread().getId() +"", testMethodResultsMap.get());
        }
    }

    @Override
    public void onTestFailure(ITestResult result) {}
    @Override
    public void onTestSkipped(ITestResult result) {}
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
    @Override
    public void onStart(ITestContext context) { }
    @Override
    public void onFinish(ITestContext context) { }
}
import java.util.HashMap;
导入java.util.LinkedHashMap;
导入org.testng.ISuite;
导入org.testng.ISuiteListener;
导入org.testng.ITestContext;
导入org.testng.ITestListener;
导入org.testng.ITestResult;
公共类侦听器实现ITestListener、ISuiteListener{
public static ThreadLocal executionDetailsMap=null;
公共静态ThreadLocal testMethodResultsMap=null;
@凌驾
public void onStart(ISuite){
System.out.println(“=>在套件启动时”);
executionDetailsMap=new ThreadLocal(){
@凌驾
受保护的HashMap initialValue(){
返回新的HashMap();
}
};  
System.out.println(executionDetailsMap);
}
@凌驾
公共作废完成(ISuite){
System.out.println(“==>在套件完成时”+executionDetailsMap);
System.out.println(executionDetailsMap.get());
System.out.println(“----”+Thread.currentThread().getId());
System.out.println(testMethodResultsMap);
}
@凌驾
公共void onTestStart(ITestResult结果){
System.out.println(Thread.currentThread().getId());
如果(null!=testMethodResultsMap){
已同步(testMethodResultsMap){}
}否则{
testMethodResultsMap=new ThreadLocal(){
@凌驾
受保护的LinkedHashMap初始值(){
返回新的LinkedHashMap();
}
};
}
}
@凌驾
公共void onTestSuccess(ITestResult结果){
已同步(executionDetailsMap){
executionDetailsMap.get().put(Thread.currentThread().getId()+“”,testMethodResultsMap.get());
}
}
@凌驾
public void onTestFailure(ITestResult结果){}
@凌驾
已跳过公共void onTestSkipped(ITestResult结果){}
@凌驾
public void ontestFailed但未成功百分比(ITestResult结果){}
@凌驾
public void onStart(ITestContext上下文){}
@凌驾
公共void onFinish(ITestContext上下文){}
}
parallelSuiteTest.xml

    <?xml version="1.0" encoding="UTF-8"?>
<suite name="Parallel test suite" parallel="tests" >
    <listeners>
        <listener class-name="com.test.Listener" />
    </listeners>
    <test name="TC1" >
        <classes>
            <class name="com.test.ThreadTest" />
            <methods>
                <include name="testMethod" />
            </methods>
        </classes>
    </test>

    <test name="TC2" >
        <classes>
            <class name="com.test.ThreadTest" />
            <methods>
                <include name="testMethod" />
            </methods>
        </classes>
    </test>
</suite>


您创建了一个ThreadLocal HashMap,这样每个线程都有自己的副本。@alpert是的,我只使用了ThreadLocal HashMap,但仍然存在问题如果删除ThreadLocal并只使用HashMap怎么办?@vinod您不应该使用ThreadLocal:)