我正在开发一个项目,我将从多线程代码中生成多个线程。
假设我正在生成10个线程,那么我需要确保每个线程都应该在特定的持续时间内运行。
例如,如果我希望each thread
运行30 minutes
,那么在config.properties
文件中,我将TOTAL_RUNNING_TIME=30
所以我提出了以下设计,以确保每个线程都在运行30 minutes
。
private static long durationOfRun;
private static long sleepTime;
public static void main(String[] args) {
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(threads);
try {
readPropertyFile();
for (int i = 0; i < threads; i++) {
service.submit(new ReadTask(durationOfRun, sleepTime));
}
}
}
private static void readPropertyFile() throws IOException {
prop.load(Read.class.getClassLoader().getResourceAsStream("config.properties"));
threads = Integer.parseInt(prop.getProperty("NUMBER_OF_THREADS"));
durationOfRun = Long.parseLong(prop.getProperty("TOTAL_RUNNING_TIME"));
sleepTime = Long.parseLong(prop.getProperty("SLEEP_TIME"));
}
下面是我的ReadTask类。
class ReadTask implements Runnable {
private long durationOfRun;
private long sleepTime;
public ReadTask(long durationOfRun, long sleepTime) {
this.durationOfRun = durationOfRun;
this.sleepTime = sleepTime;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun*60*1000);
//Each thread is running less than endTime
while(System.currentTimeMillis() <= endTime) {
//Do whatever you want to do
}
Thread.sleep(sleepTime);
}
}
如果你看一下我的run方法,我会有一个while循环来检查时间。因此,使每个线程运行特定持续时间的这种方法是否正确?或者还有更好的方法吗?如果还有其他更好的方法,或者这也可以达到目的,请忽略我的无知?
请告诉我这里是否还有线程安全问题?
我正在寻找的是每个线程应该运行30分钟,如果该线程的时间已经完成,那么完成当前正在运行的任务,之后不再采取任何其他操作,就像对shutdown
我们ExecutorService
。如果有更好的方法或更好的设计。请给我一些例子,以便我可以从我的知识角度学习这些东西。谢谢你的帮助。
更新: -
如果你在run方法中查看我的while循环,在while循环中我将尝试创建Select call to the database
。所以我看到的是这样的 - 一旦该线程的时间结束,它将不会对数据库进行任何其他选择调用并完成之前正在执行的任何操作。就像shutdown
适用于ExecutorService
一样。
我不希望这种情况 - 只要该线程的时间结束,它就会使线程超时,因为特定的线程在那段时间内选择了数据库?
答案 0 :(得分:1)
我对这种设计的一个担忧是,如果在while循环中完成的工作量对我们来说需要更多的时间呢?
例如
while(System.currentTimeMillis() <= endTime) {
calaculateTheMeaningOfLife();
}
现在发生了什么?什么阻止线程,或鼓励它检查超时?如果您有阻塞操作,例如文件或套接字读/写
,则会发生同样的情况你可以试着打断这个帖子,但是没有人会知道这会有所帮助
答案 1 :(得分:0)
您可以设置执行者的时间限制。您需要强制执行Executors返回的执行程序并设置时间限制:
ThreadPoolExecutor service = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);
service.setKeepAliveTime(1800, TimeUnit.SECONDS);
取自Brian Goetz的“Java Concurrency in Practice”。