MutableInteger不被视为线程安全类,因为从不同线程调用时它通常可能返回过时的值。
class MutableInteger{
private int value;
public int get(){
return value;
}
public void set(int value){
this.value=value;
}
}
这是我的线程实现:- 有一个主线程(主方法),并从中调用 MyThread。
class MyThread extends Thread{
private int num;
public void set(int num){
this.num=num;
}
public void run(){
MutableInteger mi=new MutableInteger();
mi.set(num);
System.out.println("Mythread "+mi.get());
}
}
class MutableIntegerTest{
public static void main(String[] args){
MyThread t1=new MyThread();
t1.set(10);
t1.start();
MutableInteger mi=new MutableInteger();
mi.set(99);
System.out.println("Main thread" +mi.get());
}
}
现在这是我无法理解的地方。为了访问状态变量 value
,我们需要使用 MutableInteger
类的 getter 和 setter 方法,因此对于每次访问,我们都需要实例化 MutableInteger
类。现在根据理论,每个对象都有自己的实例变量副本。在我的实现中,两个线程仅通过 MutableInteger
实例访问 value
变量。在我的例子中,value
不在线程之间共享,从而使我的 MutableInteger 线程安全。
我应该怎样做才能使线程共享值
?我是否应该公开该对象,以便可以在两个线程中使用相同的对象?但这不会将该对象公开给所有可用的类和线程吗?
我做错了什么吗?
最佳答案
如果您想测试您的 MutableInteger
以亲眼看看它不是线程安全的,则必须在线程之间共享一个对象。如果每个线程创建自己的 MutableInteger
实例,那么正如您所注意到的,您实际上并没有测试该特定事物,因为它只能由创建它的单个线程访问。
因此您需要创建一个实例,并让两个线程都使用它。例如:
可运行的对象(最好使用扩展Thread
的类):
class MutableIntegerTester implements Runnable {
private int num;
private MutableInteger mutableInteger;
public MutableIntegerTester(int num, MutableInteger mutableInteger) {
this.num = num;
this.mutableInteger = mutableInteger;
}
@Override
public void run() {
for ( int i = 0; i < 1000; i++ ) {
mutableInteger.set(mutableInteger.get() + num);
}
System.out.println(mutableInteger.get());
}
}
请注意,我将 run
方法更改为可以让您更好地看到安全性缺乏的地方。您既有非原子读取和添加,也有“陈旧”(非 volatile )变量的使用。
要共享对象,请使用:
public static void main(String[] args) {
MutableInteger sharedObject = new MutableInteger();
MutableIntegerTester tester1 = new MutableIntegerTester(10, sharedObject);
MutableIntegerTester tester2 = new MutableIntegerTester(99, sharedObject);
new Thread(tester1).start();
new Thread(tester2).start();
}
现在,如果 mutableInteger 是线程安全的,您会期望结果始终打印 109000。但当然不会。每次运行它可能会打印不同的数字,有时甚至会为不同的线程打印不同的数字。
关于java - 如何在线程之间共享一个对象来证明它不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32583520/