[英]My timer's thread may be cheating on him with Thread.sleep?
因此,從本質上來說,我擔心在10分鍾后不會調用我的timertask的run
方法,因為我正在使主線程進入睡眠狀態10秒鍾,以避免瘋狂的CPU使用率整天運行在一個空的while循環中。 這是java main方法的代碼。
private static boolean testDone = false;
public static void main(String[] args)
{
final int minutes = 10;
final StressTest test = new StressTest(someParams);
test.start();
Timer timer = new Timer();
timer.schedule(new TimerTask(){
@Override
public void run() {
testDone = true;
int completedSynths = test.stop();
System.out.println("Completed Synths: " + completedSynths);
System.out.println("Elapsed Time in Minutes: " + minutes);
System.out.println("Throughput (synths/min): " + completedSynths/minutes);
}}, minutes*60*1000);
while(!testDone)
{
System.out.println("Still not done... sleeping for 10 secs....");
Thread.sleep(10000);
}
System.exit(0);
更瘋狂的是, while
循環中的System.out
從不打印。 我做了什么??
編輯:為StressTest對象添加偽代碼
public class StressTest
{
private SecureRandom random = new SecureRandom();
private volatile int completedSynths = 0;
private volatile boolean shouldStop = false;
private Thread[] threads;
/**
* Instantiate a new StressTest object.
*
* @param threadCount number of concurrent threads to be polling server
*/
public StressTest(int threadCount)
{
threads = new Thread[threadCount];
}
public void start()
{
System.out.println("Starting Stress Test....");
for(int i = 0; i < threads.length; i++)
{
Runnable synthCaller = new SynthApiCaller();
threads[i] = new Thread(null, synthCaller, "SynthThread" + i);
threads[i].run();
}
}
public int stop()
{
System.out.println("Stopping Stress Test...");
shouldStop = true;
return completedSynths;
}
private String randId()
{
return new BigInteger(130, random).toString(32);
}
private class SynthApiCaller implements Runnable
{
@Override
public void run()
{
while(!shouldStop)
{
try
{
//this class makes an HTTP request to a server and then writes result to a file
MyClass.writeFile( "someFileLoc/file.data");
completedSynths++;
Runtime.getRuntime().exec("rm -r " + fileLoc);
System.out.println("Synth # " + completedSynths);
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
System.out.println("Thread terminated...");
}
}
}
我擔心在10分鍾后不會調用我的timertask的run方法,因為我正在使主線程進入睡眠狀態10秒鍾
主線程中的Thread.sleep(...)
不會影響Timer
的運行。 如果計時器在10分鍾后沒有運行,那么test.stop()
是否可能阻塞?
重要的是要意識到,如果測試在主線程中啟動,然后在Timer
線程中停止,則必須進行一些同步。 我假設測試正在另一個線程中運行。 您可能需要將它同步,然后在Timer
線程內部調用類似於:
synchronized (test) {
test.start();
}
如果您想知道是否完全調用了計時器,我將在您的計時器任務中設置一個斷點,其中將其設置為testDone = true
然后查看它是否到達那里。 這是一個在eclipse中使用調試器的好教程 。
更瘋狂的是,while循環中的System.out從不打印。 我做了什么??
正如@assylias所提到的,while循環中未顯示的System.out(...)
必須表示testDone
設置為true。 由於testDone
正在不同的線程中進行更新和訪問,因此您需要確保它也是volatile
。
我只是在沒有test.start()
和stop()
情況下運行了您的代碼示例,它似乎運行良好。 問題可能出在您的test
代碼中。
Still not done... sleeping for 10 secs....
Still not done... sleeping for 10 secs....
...
Completed Synths: 1
Elapsed Time in Minutes: 10
Throughput (synths/min): 0
現在你已經添加了更多代碼,這里有一些評論:
completedSynths++;
應該更改為AtomicInteger
。 ++不是原子操作,因此即使字段是可變的,多個線程也可以覆蓋彼此的增量。
如果您試圖等待線程完成,而不是等待10分鍾,我建議使用thread[i].join()
調用thread[i].join()
。 更好的方法是使用ExecutorService
並使用awaitTermination(...)
方法。
您調用shouldStop = true;
然后返回completedSynths;
。 您可能希望等待線程完成或某事。
我不會將null
ThreadGroup
傳遞給Thread
構造函數。 只需使用不帶ThreadGroup
的構造函數即可。
我建議讓testDone變得不穩定。 實際上,除了進行更改的線程外,我看不到任何迫使對testDone進行更改的結果可見於線程中的讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.