我有一個類可以異步記錄eyetracking數據。有記錄過程的方法有start
和stop
。數據收集在一個集合中,只有在記錄線程完成其工作時才能訪問集合。它基本上封裝了所有的線程和同步,所以我的庫的用戶不必這樣做。單元測試必須手動中斷的異步計算
全副縮短代碼(仿製藥和錯誤處理省略):
public class Recorder {
private Collection accumulatorCollection;
private Thread recordingThread;
private class RecordingRunnable implements Runnable {
...
public void run() {
while(!Thread.currentThread().isInterrupted()) {
// fetch data and collect it in the accumulator
synchronized(acc) { acc.add(Eyetracker.getData()) }
}
}
}
public void start() {
accumulatorCollection = new Collection();
recordingThread = new Thread(new RecordingRunnable(accumulatorCollection));
recordingThread.start();
}
public void stop() {
recordingThread.interrupt();
}
public void getData() {
try {
recordingThread.join(2000);
if(recordingThread.isAlive()) { throw Exception(); }
}
catch(InterruptedException e) { ... }
synchronized(accumulatorCollection) { return accumulatorCollection; }
}
}
的用法很簡單:
recorder.start();
...
recorder.stop();
Collection data = recorder.getData();
我對整個事情的問題是如何對其進行測試。目前,我做這樣的:
recorder.start();
Thread.sleep(50);
recorder.stop();
Collection data = recorder.getData();
assert(stuff);
這工作,但它具有不確定性,並減慢測試套件相當多的(我畫這些測試,集成測試,所以他們必須單獨運行繞過這個問題)。
有沒有更好的方法?
你睡着了,所以你可以收集數據,或以確保過程已經開始? – shmosel
我這樣做來收集數據,否則我只會得到一個單一的數據包左右。 –
看起來您正在重塑[Future](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html),您可以通過[將任務提交給一個ExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.lang.Runnable))。 –