我正在开发一个多线程程序,我正在尝试确保每个线程都在运行30 minutes
。假设我们有10 threads
,则10
中的每个帖子都应该为30 minutes
运行。
以下是我的代码 -
class ThreadTask implements Runnable {
private final long endTime;
public ThreadTask(long endTime) {
this.endTime = endTime;
}
@Override
public void run() {
while (System.currentTimeMillis() <= endTime) {
// do something meaningful
}
}
}
public class TestPool {
public static void main(String[] args) {
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(1000);
long startTime = System.currentTimeMillis();
long endTime = startTime + (30 * 60 * 1000);
for (int i = 0; i < threads; i++) {
service.submit(new ThreadTask(endTime));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
现在我的问题是 -
以上代码是否保证每个线程同时启动并运行30 minutes
?我不确定将线程放入线程池需要多长时间。但看起来有些线程可能会稍微延迟而且它们不能正好运行30 minutes
,可能不到30分钟。
我正在寻找每个线程应该同时启动它们应该 完全运行
30 minutes
答案 0 :(得分:1)
简短回答:不,所有主题都不会同时启动(取决于您的容忍度,它可能会非常微不足道)。根据有意义的事情,每个线程运行30分钟的可能性很小(再次在这里,你的时间粒度可能会使这个断言错误)。
潜在客户:
修改强>:
public class TestPool {
public static void main(String[] args) {
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);
long startTime = System.currentTimeMillis();
long endTime = startTime + (30 * 60 * 1000);
ThreadTask[] threadTasks = new ThreadTask[threads];
for (int i = 0; i < threads; i++) {
threadTasks[i] = new ThreadTask(endTime);
}
for (ThreadTask tt : threadTasks) {
service.submit(tt);
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
答案 1 :(得分:0)
乍一看,这看起来像是一个有点不切实际的多线程练习项目。但你说我正在研究多线程程序,这表明它有一个真实的应用程序背景。
如果是这种情况:不要因为可以而创建1000个线程。相反,说出你真正想要实现的目标。
关于您的要求:要以最短的延迟几乎同时启动所有主题,您可以prestartAllCoreThreads
ThreadPoolExecutor
。在运行方法中提交具有// do something meaningful
的Runnables。要将运行时间限制为30分钟,请安排TimerTask在30min后使用shutdownNow关闭ThreadPoolExecutor。创建ThreadPoolExecutor时,您可以使用固定大小的BlockingQueue,其大小与所需的线程数一样,以避免提交太多的作业。
答案 2 :(得分:0)
考虑使用倒计时锁存器来实现最大并行度。基本上你可以创建单数/静态countdownLatch,总计数为1,让多个线程等待相同的倒计时。检查下面我做了什么
决定线程开始时间的主线程。
package mylab.threads;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainThread extends TimerTask {
private static CountDownLatch countDown = new CountDownLatch(1);
private ExecutorService es = Executors.newCachedThreadPool();
@Override
public void run() {
try {
Thread1 thread1 = new Thread1();
thread1.setDoneSignal(countDown);
es.submit(thread1);
Thread2 thread2 = new Thread2();
thread2.setDoneSignal(countDown);
es.submit(thread2);
System.out.println("waiting main.. ");
synchronized(this) {
this.wait(2000);
}
System.out.println("kick off threads..");
countDown.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
定义要并行运行的线程
package mylab.threads;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
public class Thread1 extends TimerTask{
private CountDownLatch doneSignal = null;
/**
* @return the doneSignal
*/
public CountDownLatch getDoneSignal() {
return doneSignal;
}
/**
* @param doneSignal the doneSignal to set
*/
public void setDoneSignal(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
@Override
public void run() {
try {
this.doneSignal.await();
System.out.println("get going thread 1 -"+new Date().getTime());
synchronized(this) {
this.wait(3000);
}
System.out.println("Exiting thread 1 - "+new Date().getTime());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package mylab.threads;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
public class Thread2 extends TimerTask{
private CountDownLatch doneSignal = null;
/**
* @return the doneSignal
*/
public CountDownLatch getDoneSignal() {
return doneSignal;
}
/**
* @param doneSignal the doneSignal to set
*/
public void setDoneSignal(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
@Override
public void run() {
try {
this.doneSignal.await();
System.out.println("get going thread 2 -"+new Date().getTime());
synchronized(this) {
this.wait(3000);
}
System.out.println("Exiting thread 2 - "+new Date().getTime());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最后运行主线程。
package mylab.threads;
public class ThreadTest {
/**
* @param args
*/
public static void main(String[] args) {
MainThread mt = new MainThread();
mt.run();
}
}
这是输出
waiting main..
kick off threads..
get going thread 1 -1387513662107
get going thread 2 -1387513662107
Exiting thread 1 - 1387513665108
Exiting thread 2 - 1387513665108