是否有可能从Java中的工作者线程调用主线程?
我有一个名为action()的方法,用于部署三个线程。每个已部署的线程或工作线程都基于布尔类型为true的单个实例变量落入while循环中,例如boolean doWork = true,每个线程将有一个while(doWork){}循环。是否有可能从Java中的工作者线程调用主线程?
当线程完成作业时,将doWork设置为false,以阻止所有线程循环。然后我想以某种方式让主线程调用action()方法来重新部署线程来完成另一项工作。 (如果我使用其中一个工作线程来调用action()方法,那么它是否正常?)一旦它调用action()方法并且不知何故死亡,工作线程会终止吗?
我限制比如将两个线程简单
感谢
class TestThreads{
boolean doWork = true;
void action(){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
}
//innerclasses
class ThreadOne implements Runnable{
Thread trd1;
public ThreadOne(){//constructor
if(trd1 == null){
trd1 = new Thread(this);
trd1.start();
}
}
@Override
public void run(){
while(doWork){
//random condition
//would set doWork = false;
//stop all other threads
}
action();//is the method in the main class
}
}
class ThreadTwo implements Runnable{
Thread trd2;
public ThreadTwo(){//constroctor
if(trd2 == null){
trd2 = new Thread(this);
trd2.start();
}
}
@Override
public void run(){
while(doWork){
//random condition
//would set doWork = false;
//stop all other threads
}
action();//is the method in the main class
}
}
}
这个怎么样实现:
声明类的成员doWork
,为当前活动的线程一个计数器和一个同步对象:
private volatile boolean doWork = true;
private AtomicInteger activeThreads;
private Object locker = new Object();
在主:
while(true) {
// call action to start N threads
activeThreads = new AtomicInteger(N);
action(N);
// barrier to wait for threads to finish
synchronized(locker) {
while(activeThreads.get() > 0) {
locker.wait();
}
}
}
在螺纹体:
public void run() {
while(doWork) {
...
// if task finished set doWork to false
}
// signal main thread that I've finished
synchronized(locker) {
activeThreads.getAndDecrement();
locker.notify();
}
}
这是一个有点难以给你无需任何代码的精确解。这听起来像是你正在描述生产者/消费者模式,你给一组工作者线程一些任务,当他们完成时,你给他们更多。
这是一个web page,它确实可以描述做什么。
另请参阅ExecutorService,它允许您提交Runnable并让它们执行。
一个简单的解决方案是让主线程睡眠:
static boolean doWork = true; // better to use AtomicBoolean
void action() {
// start workers, which eventually set doWork = false
while (doWork) {
Thread.sleep(/**time in millis**/); // main thread waits for workers
}
// logic to run action() again, etc.
}
主线程启动工人,定期唤醒,以检查他们是否已经终止。既然主线是一个“仲裁者”,它可能不应该为了一个孩子的复活而死去。
参考
骨架代码
// OP said 3 threads...
ExecutorService xs = Executors.newFixedThreadPool(3);
...
// repeat the following as many times as you want...
// this is the setup for his 3 threads - as Callables.
ArrayList<Callable<T>> my3Callables = new ArrayList<Callable<T>>();
my3Callables.add(callable1);
my3Callables.add(callable2);
my3Callables.add(callable3);
try {
List<Future<T>> futures = xs.invokeAll(my3Callables);
// below code may not be needed but is useful for catching any exceptions
for (Future<T> future : futures) {
T t = future.get();
// do something with T if wanted
}
}
catch (ExecutionException ee) {
// do something
}
catch (CancellationException ce) {
// do something
}
catch (InterruptedException ie) {
// do something
}
I”我会扩大我的评论(即使@babernathy添加到他的答案)。
通常,你必须要执行一些作品的线程池,和你有一个主线程管理,你想要做的工作项目中,ExecutorService
提供了理想的框架。
在你的主对象中,你可以创建一个服务的实例(带有你想要的线程数),然后当你生成一个工作,提交给服务,服务将选择下一个可用的线程从池中执行。
如果您对是否已完成特定工作有依赖性,您可以使用类似于CountDownLatch
的内容来跟踪线程何时完成工作。我的观点是,现在有很多这类活动的框架,不需要再次从头开始......
为什么不使用'ExecutorService'来设计类似于你正在做的事情? – Nim 2012-02-01 17:43:18
即使我已经对upvoted @Nim评论,让我重复一遍:看看这种类型的事情ExecutorService。 – user949300 2012-02-01 17:45:09
@Nim也许这会更好,如果你写了更多的细节的答案,因为它可能会感兴趣其他人 – 2012-02-01 17:45:50