Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java getClass().getName()返回null_Java_Multithreading_Thread Safety_Testng - Fatal编程技术网

Java getClass().getName()返回null

Java getClass().getName()返回null,java,multithreading,thread-safety,testng,Java,Multithreading,Thread Safety,Testng,我正在使用testNG为我们的测试编写者提供一个“框架”,以加快测试的开发。为了实现这一点,我有一个抽象的测试类。所有的书面测试都来自这个测试类。testNG可以并行运行这些测试。现在我注意到,有时在@BeforeClass方法中,我的简单“getClass().getName()”方法在并行执行时返回null private static ThreadLocal<String> className; @BeforeClass public void init(){

我正在使用testNG为我们的测试编写者提供一个“框架”,以加快测试的开发。为了实现这一点,我有一个抽象的测试类。所有的书面测试都来自这个测试类。testNG可以并行运行这些测试。现在我注意到,有时在@BeforeClass方法中,我的简单“getClass().getName()”方法在并行执行时返回null

private static ThreadLocal<String> className;

@BeforeClass
public void init(){
        initName();
        className.set(getClass().getName());            
        log("Starting test " + className.get());
}

private synchronized void initName(){
    if(className == null){
        className = new ThreadLocal<>();
    }
}
一些评论:
Threadlocal ClassName必须是静态的(我稍后在@Dataprovider中使用它的值)
由于它是随机发生的,并且在任何测试中都可能发生,所以我假设这是一个线程安全问题,但我不知道如何使“getClass().getName()”更线程安全


感谢您的帮助

您似乎有比赛状态。如果一个线程在其他线程调用
log
之前调用
initName
,则新的
ThreadLocal
将没有值,即返回
null


这里没有线程安全保护
initName
中的
null
检查
initName

跳过
initName
中的延迟初始化!它不是线程安全的

相反,直接初始化
ThreadLocal
字段(并注意
final
):

private static final ThreadLocal className=new ThreadLocal();

(顺便问一下:为什么您需要一个
ThreadLocal
来保存当前类的名称?只要调用
getClass().getName()
),您随时都可以轻松地获得它。

我假设输入initName()的第一个线程将阻止其他线程,因为它已同步。这个假设错了吗?如果是,那么阻止其他线程的正确方法是什么?@MajorT您的
initName
方法在实例上同步,而不是在类上同步,因此,在不同实例上调用的
initName
将并行运行。我需要它,因为我在@dataprovider方法中动态创建数据,该方法是静态的,我需要获取该静态方法中子类的类名。我现在意识到更好的方法可能是使用testNG工厂,但现在太晚了,所以我需要一个变通方法。我现在将尝试您的“非懒惰”初始化:)之前阅读的期末考试真的做到了:)非常感谢!
...
Starting test com.mycompany.testsets.LocalTestSet$IntegrationTest3
Starting test null
Starting test com.mycompany.testsets.LocalTestSet$IntegrationTest1
...
private static final ThreadLocal<String> className = new ThreadLocal<>();