我是Threads的新手。我正在阅读Java Concurrency in Practice。我在书中找到了以下例子。
@NotThreadSafe
public class UnSafeSequence
{
private int value;
public int getNext()
{
return value++;
}
}
我想通过编写访问此类的几个线程(或更多)来测试此代码,以获得线程安全感。
我尝试过这些,但不确定如何测试这些例子。
class MyThread implemented Runnable
{
public void run()
{
//Should I create a new object for UnSafeSequence here ?
}
}
感谢您的帮助。
答案 0 :(得分:5)
如果每个线程都有自己的UnSafeSequence
实例,那么它就不会显示问题。您需要做的是在UnSafeSequence
个实例之外创建MyThread
的实例,并将其传递到每个MyThread
的构造函数中。
UnSafeSequence unsafe = new UnSafeSequence();
...
new Thread(new MyThread(unsafe)).start();
new Thread(new MyThread(unsafe)).start();
...
class MyThread implemented Runnable {
private UnSafeSequence unsafe;
public MyThread(UnSafeSequence unsafe) {
this.unsafe = unsafe;
}
public void run() {
...
unsafe.getNext();
...
}
}
在学习线程时,请务必阅读ExecutorService
和其他优秀课程。这是一个good tutorial from Sun^H^H^H Oracle。
答案 1 :(得分:2)
不,如果您在UnSafeSequence
中创建run
的新实例,则每个帖子都会有自己的value
成员,这不会显示问题。您有两个选择:
将value
和getNext()
设为静态,并使用UnSafeSequence.getNext()
创建共享对象并在创建时将其传递给您的线程
class MyThread implemented Runnable
{
UnSafeSequence unsafe;
MyThread(UnSafeSequence unsafe) { this.unsafe = unsafe; }
public void run() { /* call unsafe.getNext(); */ }
}
答案 2 :(得分:0)
您可以为每个线程创建一个UnSafeSequence
实例,这将是完全安全的。如果对N个线程执行此操作,则将具有N个值的副本,这是有问题的非同步数据。
如果要以线程不安全的方式访问它,则需要创建UnSafeSequence
的单个实例,然后从多个线程调用getNext()。