gpt4 book ai didi

java - 实例和静态方法的并发测试的有效性

转载 作者:太空宇宙 更新时间:2023-11-04 08:45:23 25 4
gpt4 key购买 nike

我想验证我编写的以下测试,以验证两个线程可以同时访问静态同步方法和非静态同步方法(因为锁位于不同的对象上)。我得到了结果,但想知道我的解释是否正确

我运行了下面的代码,我看到变量 i 的值有时分别从静态和非静态方法中打印出来。这是静态和非静态方法在两个不同对象上拥有锁并且两个线程可以同时访问它们这一事实的有效证明。

代码

import java.util.ArrayList;
import java.util.List;

public class TestStaticSynchronize {

public static final TesteeClass obj = new TesteeClass();

/**
* @param args
*/
public static void main(String[] args) {
for(int i = 0; i < 50; i++) {
Runner run = new Runner(i);
Thread th = new Thread(run);
th.start();
}
}

static class Runner implements Runnable {

private int i;

public Runner(int i) {
this.i = i;
}

public void run() {
if(i % 2 == 0) {
TesteeClass.staticSync();
} else {
obj.instanceSync();
}
}

}
}

class TesteeClass {

private static List<Integer> testList = new ArrayList<Integer>();


public static synchronized void staticSync() {
System.out.println("Reached static synchronized method " + testList.size());
testList.add(1);
}

public synchronized void instanceSync() {
System.out.println("Reach instance synchronized method " + testList.size());
testList.add(1);
}
}

最佳答案

您的评估是正确的。这就是原因。

因此,采用同步实例方法,让我们用等效的同步块(synchronized block)表示法重写它:

public void instanceSync() {
synchronized( this ) {
System.out.println("...");
testList.add( 1 );
}
}

当您编写同步方法时,它与锁定周围实例(即 this)是一样的。对于静态方法,此参数不存在,那么静态的等效同步块(synchronized block)是什么?它锁定了 Class 对象。

public void classSync() {
synchronized( TestClass.class ) {
System.out.println("...");
testList.add( 1 );
}
}

因此,this 实例与代表 TestClass 类的对象是不同的对象。这意味着使用了两种不同的锁,这导致了您发现的问题。最后你的测试程序非常危险并且不是线程安全的。实例方法,特别是在多线程情况下使用时,不应接触静态成员。通过静态方法路由这些访问是可以的,但直接访问充其量是一种糟糕的形式,更糟糕的是一个严重的错误。

有一种方法可以让它们锁定同一个对象来编写程序,但我认为考虑为什么要编写这样的代码很重要。是因为您真的只希望很多地方共享这样的单个结构,但在获取对单个对象的引用时遇到困难吗?这是软件架构的核心及其在多线程应用程序中发挥的重要作用。我怀疑有比使用静态成员更好的选择,并且只需使用所有位置都有引用的单个实例(希望不使用单例模式、全局静态等)。

关于java - 实例和静态方法的并发测试的有效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4446107/

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