所以基本上我担心我的timertask的run
方法在10分钟后没有被调用,因为我让主线程休眠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);
即使比较疯狂,System.out
循环中的while
也永远不会打印。我做了什么?
编辑:为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...");
}
}
}
答案 0 :(得分:4)
我担心我的timertask的run方法在10分钟后没有被调用,因为我正在让主线程休眠10秒
主线程中的Thread.sleep(...)
不会影响Timer
的运行。如果计时器在10分钟后没有运行,那么test.stop()
是否可以阻止?
重要的是要意识到,如果测试在主线程中启动,然后在Timer
线程中停止,则需要进行一些同步。我假设测试正在另一个线程中运行。您可能需要将其同步,然后在Timer
线程中进行同步,您可以调用类似:
synchronized (test) {
test.start();
}
如果您不熟悉Java同步,则有一些good tutorials online。
如果您想知道是否正在调用计时器,我会在您的计时器任务中设置一个断点,其中设置testDone = true
并查看它是否到达那里。
这是一个good tutorial of using a debugger in 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()
。更好的方法是使用ExecutorService
并使用awaitTermination(...)
方法。
您致电shouldStop = true;
,然后返回completedSynths;
。您可能希望等待线程完成或其他什么。
我不会将null
ThreadGroup
传递给Thread
构造函数。只需使用不带ThreadGroup
。
答案 1 :(得分:3)
我建议让testDone变得不稳定。实际上,我没有看到任何强制更改testDone的内容对于除了进行更改的线程之外的线程中的读取是可见的。