2013-02-25 80 views
3

我是新来的主题。我正在阅读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 ? 
    } 
} 

感谢您的帮助。

+2

的问题把它传递给你的线程使用非线程安全的代码是代码可以执行n次,并且仍然可以产生n次正确的结果。 – 2013-02-25 15:36:19

回答

5

如果每个线程都有其自己的实例UnSafeSequence那么它不会证明问题。你需要做的是在MyThread实例之外创建一个UnSafeSequence的实例,并将它传递给每个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

0

您可以为每个线程创建一个单一的UnSafeSequence实例,这将是完全安全的。如果您为N个线程执行此操作,则将有N个值的副本,即所讨论的非同步数据。

如果您想以线程不安全的方式访问它,您需要创建一个UnSafeSequence的实例,然后从多个线程中调用getNext()。

2

不,如果您在run中创建了UnSafeSequence的新实例,则每个线程都将拥有自己的value成员,并且这不会显示问题。你有两个选择:

  • valuegetNext()静态与UnSafeSequence.getNext()

  • 把它创建一个共享对象,并在创建

    class MyThread implemented Runnable 
    { 
        UnSafeSequence unsafe; 
        MyThread(UnSafeSequence unsafe) { this.unsafe = unsafe; } 
        public void run() { /* call unsafe.getNext(); */ } 
    }