Java 如何检查线程是否已完成其任务?
好的,我创建了几个线程来完成一些复杂的任务。现在我如何检查每个线程是否成功完成Java 如何检查线程是否已完成其任务?,java,multithreading,Java,Multithreading,好的,我创建了几个线程来完成一些复杂的任务。现在我如何检查每个线程是否成功完成 class BrokenTasks extends Thread { public BrokenTasks(){ super(); } public void run(){ //Some complex tasks related to Networking.. //Example would be fetching some data from the
class BrokenTasks extends Thread {
public BrokenTasks(){
super();
}
public void run(){
//Some complex tasks related to Networking..
//Example would be fetching some data from the internet and it is not known when can it be finished
}
}
//In another class
BrokenTasks task1 = new BrokenTasks();
BrokenTasks task2 = new BrokenTasks();
BrokenTasks task3 = new BrokenTasks();
BrokenTasks task4 = new BrokenTasks();
task1.start();
.....
task4.start();
那么,我如何检查这些任务是否从中成功完成
i) 主程序(主线程)
ii)来自每个连续线程。例如:检查task1是否已在task2内结束。您可以使用
Thread.isAlive
方法,请参阅API:“如果线程已启动但尚未死亡,则该线程处于活动状态”。这是在task2 run()中测试task1.isAlive()的
要从task2中查看task1,您需要将其作为参数传递给task2的构造函数,或者使tasks字段而不是本地变量。如果线程尚未完成其任务,则它仍然处于活动状态。因此,为了测试线程是否已完成其任务,您可以使用
isAlive()
方法。通常,您只需在想要完成的线程上加入即可。在联接完成之前,线程不会继续。例如:
// await all threads
task1.join();
task2.join();
task3.join();
task4.join();
// continue with main thread logic
(我可能会把任务放在一个列表中以便更干净地处理)使用线程的一个好方法是不要直接使用它们。而是创建一个线程池。然后在POJO任务封装中有一个字段,该字段仅在计算结束时设置 当另一个线程可以看到状态时,可能会有3-4毫秒的延迟,但最后JVM会这样做。只要其他线程不重写它。您可以通过确保每个任务都有一个唯一的要执行的工作实例和状态来保护它,其他线程只需每隔1-5秒轮询一次,或者确保工作人员在完成后调用一个侦听器。 我用过的图书馆是我自己的 要使用:在服务器启动或静态块中:
package org.s2n.ddt.util;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.s2n.ddt.util.threads.PoolOptions;
import org.s2n.ddt.util.threads.DdtPools;
public class PoolTest {
private static final Logger logger = Logger.getLogger(PoolTest.class);
@Test
public void test() {
PoolOptions options = new PoolOptions();
options.setCoreThreads(2);
options.setMaxThreads(33);
DdtPools.initPool("a", options);
Do1 p = null;
for (int i = 0; i < 10; i++) {
p = new Do1();
DdtPools.offer("a", p);
}
LangUtils.sleep(3 + (int) (Math.random() * 3));
org.junit.Assert.assertNotNull(p);
org.junit.Assert.assertEquals(Do1.getLs(), 10);
}
}
class Do1 implements Runnable {
volatile static long l = 0;
public Do1() {
l++;
}
public void run() {
// LangUtils.sleep(1 + (int) (Math.random() * 3));
System.out.println("hi " + l);
}
public static long getLs() {
return l;
}
}
package org.s2n.ddt.util;
导入org.apache.log4j.Logger;
导入org.junit.Test;
导入org.s2n.ddt.util.threads.PoolOptions;
导入org.s2n.ddt.util.threads.DdtPools;
公共类池测试{
私有静态最终记录器=Logger.getLogger(PoolTest.class);
@试验
公开无效测试(){
PoolOptions=newpooloptions();
选项。setCoreThreads(2);
选项。setMaxThreads(33);
初始化池(“a”,选项);
do1p=null;
对于(int i=0;i<10;i++){
p=新的Do1();
DdtPools.报价(“a”,p);
}
sleep(3+(int)(Math.random()*3));
org.junit.Assert.assertNotNull(p);
Assert.assertEquals(Do1.getLs(),10);
}
}
类Do1实现可运行的{
挥发性静态长l=0;
公共Do1(){
l++;
}
公开募捐{
//sleep(1+(int)(Math.random()*3));
系统输出打印项次(“hi”+l);
}
公共静态长getLs(){
返回l;
}
}
你不应该做的事情:
*不要每10-15毫秒做一次事情
*除非是学术性的,否则不要自己做文章
*对于97%的情况,不要让它变得更复杂您可以使用
Callable
和ForkJoinPool
执行此任务
class BrokenTasks implements Callable {
public BrokenTasks(){
super();
}
public Object call() thrown Exception {
//Some complex tasks related to Networking..
//Example would be fetching some data from the internet and it is not known when can it be finished
}
}
//In another class
BrokenTasks task1 = new BrokenTasks();
BrokenTasks task2 = new BrokenTasks();
BrokenTasks task3 = new BrokenTasks();
BrokenTasks task4 = new BrokenTasks();
ForkJoinPool pool = new ForkJoinPool(4);
Future result1 = pool.submit(task1);
Future result2 = pool.submit(task2);
Future result3 = pool.submit(task3);
Future result4 = pool.submit(task4);
value4 = result4.get();//blocking call
value3 = result3.get();//blocking call
value2 = result2.get();//blocking call
value1 = result1.get();//blocking call
之后别忘了关闭游泳池。这里有两个不同的问题
You can use the following..
task1.join();
task2.join();
task3.join();
task4.join();
// and then check every thread by using isAlive() method
e.g : task1.isAlive();
if it return false means that thread had completed it's task
otherwise it will true
一个是线程是否仍在工作。另一个是如果任务还没有完成 线程是一种非常昂贵的解决问题的方法,当我们在java中启动线程时,VM必须存储上下文信息并解决同步问题(如锁)。所以我们通常使用线程池而不是直接使用线程。线程池的好处是我们可以使用很少的线程来处理许多不同的任务。这意味着当许多任务完成时,很少有线程保持活动状态 从线程中找不到任务状态。 线程是工作者,任务是作业。
一个线程可以逐个处理多个不同的作业。
我认为我们不应该问工人是否完成了工作。我宁愿问这项工作是否完成了 当我想检查一项工作是否完成时,我使用信号 使用信号(同步辅助) 自从JDK1.5像信号一样工作以来,有很多同步辅助工具 此对象提供一个计数器(只能设置一次并倒计时多次)。此计数器允许一个或多个线程等待,直到在其他线程中执行的一组操作完成 这是另一个有用的信号,它允许一组线程都等待彼此到达一个共同的障碍点 更多工具
在JDK
java.util.concurrent
包中可以找到更多的工具。我不确定您的确切需求,但是一些java应用程序框架有方便的抽象来处理单个工作单元或“作业”。Eclipse富客户机平台是通过其Jobs API想到的。尽管这可能有点过分
对于普通的旧Java,请看一下Future、Callable和Executor。我认为这太过分了。如果您已将作业分配给线程/池,并且已隔离该任务,则只需添加一个属性进行检查。@tgkprog属性是属于对象的变量,如果您的意思是将属性添加到任务中,我同意这是可以的。我所说的要点是我们不应该使用线程中的属性。你能详细说明一下你的答案吗?就像添加使用线程池的示例代码一样…更新后的答案将注意到app code不会生成新线程。这里的isAlive()似乎没有必要;根据定义,线程已终止,join()将返回。我知道,但如果要检查线程是否正在运行,则将使用isAlive()