2012-02-01 67 views
2

我有一个名为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 
      } 
    } 

} 
+2

为什么不使用'ExecutorService'来设计类似于你正在做的事情? – Nim 2012-02-01 17:43:18

+0

即使我已经对upvoted @Nim评论,让我重复一遍:看看这种类型的事情ExecutorService。 – user949300 2012-02-01 17:45:09

+0

@Nim也许这会更好,如果你写了更多的细节的答案,因为它可能会感兴趣其他人 – 2012-02-01 17:45:50

回答

4

这个怎么样实现:

声明类的成员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(); 
    } 
} 
1

这是一个有点难以给你无需任何代码的精确解。这听起来像是你正在描述生产者/消费者模式,你给一组工作者线程一些任务,当他们完成时,你给他们更多。

这是一个web page,它确实可以描述做什么。

另请参阅ExecutorService,它允许您提交Runnable并让它们执行。

1

一个简单的解决方案是让主线程睡眠:

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. 

} 

主线程启动工人,定期唤醒,以检查他们是否已经终止。既然主线是一个“仲裁者”,它可能不应该为了一个孩子的复活而死去。

参考

3

骨架代码

// 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 
} 
2

I”我会扩大我的评论(即使@babernathy添加到他的答案)。

通常,你必须要执行一些作品的线程池,和你有一个主线程管理,你想要做的工作项目中,ExecutorService提供了理想的框架。

在你的主对象中,你可以创建一个服务的实例(带有你想要的线程数),然后当你生成一个工作,提交给服务,服务将选择下一个可用的线程从池中执行。

如果您对是否已完成特定工作有依赖性,您可以使用类似于CountDownLatch的内容来跟踪线程何时完成工作。我的观点是,现在有很多这类活动的框架,不需要再次从头开始......

相关问题