我有四个线程在运行,我想在完成后抛出一个标志。我想要做的是将int设置为0.当一个线程完成时,它将为该int添加1。我将在最后有一个if语句,它将具有int必须等于4的条件。当发生这种情况时,将显示一条消息,指示所有线程都已完成。然而,当我尝试这样做时,它说整数必须是最终的或有效的最终。我该如何解决这个问题?
答案 0 :(得分:1)
最简单的方法就是使用Thread.join()
:
Thread[] ts = new Thread[4];
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(...);
ts[i].start();
}
for (int i = 0; i < ts.length; ++i) {
ts[i].join(); // Wait for the i-th thread to die.
}
在其他替代方案中,您可以使用CountdownLatch
,这样可以更灵活地考虑何时考虑线程&#34;完成&#34;:
Thread[] ts = new Thread[4];
final CountdownLatch latch = new CountdownLatch(ts.length);
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(new Runnable() {
@Override public void run() {
// ...
latch.countDown();
}
});
ts[i].start();
}
latch.await(); // Blocks until all threads have called `countDown()`.
答案 1 :(得分:1)
有很多方法可以做到这一点。如果您希望在其他4个线程运行时阻止主线程,则可以执行
t1.join();
t2.join();
t3.join();
t4.join();
这样你的主线程就会等待所有其他线程的执行。如果你想让每个线程递增你的标志,你可以在它们的构造函数中传递它,但你应该设置标志AtomicInteger
解决此问题的另一种方法是使用ThreadPool。您可以创建一个包含四个线程的ThreadPool,并为它们分配四个Runnable
任务。然后,您可以调用线程的.submit(Runnable)
方法。这样,4 threds将执行这四项任务。
ExecutorService的.submit()方法(使用4个线程操作的对象)返回一个所谓的Future对象。调用future.get()时,您将知道该线程已完成其任务:
ExecutorService executor = Executors.newFixedThreadPool(4);
ArrayList<Runnable> tasks = new ArrayList<>();
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
ArrayList<Future> results = new ArrayList<>();
for(Runnable t : tasks){
results.add(executor.submit(t));
}
int myIntFlag = 0;
for(Future f : results){
f.get();
myIntFlag++;
System.out.println("Part" + myIntFlag + " of the job is ready")
}
System.out.println("Whole Job ready")
答案 2 :(得分:0)
您可以通过多种方式实现相同目标。使用其中任何一个:
(a)使用Atomic Integer作为标志并增加标志计数
(b)使用CountdownLatch
(c)你也可以调整循环障碍(每个线程末尾的障碍)。
(d)使用Thead.join()
~Java Guru: Blogger在Java Interview Questions and Answers
答案 3 :(得分:0)
如果你真的想要一个int计数器变量,你可以将它标记为volatile或使用AtomicInteger。
volatile int counter = 0;
或
final AtomicInteger counter = new AtomicInteger();
请记住,您必须在主线程中循环轮询此变量,直到它为4.如果由于某种原因,其中一个线程无法增加它,则主线程将挂起永远。