2013-05-25 17 views
-1

我以为我已经采取了必要的措施,以防止数据的比赛,但似乎并未奏效......挥发性多线程数据不一致

我编写了一个层次状态机来实现硬币问答游戏。 我的一个JUnit测试检查是否预计最后一行打印到屏幕上,因为信用事件刚刚被处理。 我发现该行按预期打印在屏幕上,但用于存储上次打印值的字符串在测试点为空。

我确定字符串引用是volatile,所以我期望来自事件处理线程的写入对JUnit线程的读取是可见的。

本机类包含事件处理循环和阅读下面的代码并写入字符串参考:

private volatile String lastPrintln; 

public String lastPrintln(){ 
    return lastPrintln; 
} 

void println(String s){ 
    System.out.println(s); 
    lastPrintln = s; 
} 

测试代码如下...

@Before 
public void setUp() throws Exception { 
    machine = Objects.create(CoinQuizMachine.class); 
    machine.start(); // starts event loop thread 
} 

private void waitForEventQueueToEmpty(){ 
    while(!machine.eventQueueIsEmpty()){ 

    } 
} 

private void processTestEvent(Event e){ 
    machine.add(e); 
    waitForEventQueueToEmpty(); 
} 

@Test 
public void test2() { 
    assertEquals(Demo.class,machine.activeState().getClass()); 
    processTestEvent(new CreditEvent(1)); 
    assertEquals("Topic Choices: \nMaths\nScience",machine.lastPrintln()); 
} 
+2

我看不到'println(String)'方法被调用。如果字符串为'null',那么在调用lastPrintln()之前不会调用该方法。我会在'println(String)'中放置一个断点。 – Gray

+0

什么是您的JDK版本?易失性表现与1.5不同。 –

+0

println(String)在事件循环中被调用并且具有非空值。我正在使用1.7 – newlogic

回答

0

是的我不好的是,我发现了这个错误,在实际处理之前,我正在降低未处理事件的值,这意味着测试会提前触发,并且在最后一次打印没有更新时触发。谢谢你们的帮助。