[英]Is it possible to call the main thread from a worker thread in Java?
我有一个名为action()的方法,它可以部署三个线程。 每个部署的线程或工作线程都基于boolean类型为true的单个实例变量进入while循环,例如boolean doWork = true,每个线程都有一个while(doWork){}循环。
当线程完成作业时,会将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();
}
}
骨架代码
// 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
}
我会扩展我的评论(尽管@babernathy将此添加到他的答案中)。
通常,如果您有一个线程池 ,您希望执行某些工作,并且您有一个主线程来管理您想要完成的工作项,那么ExecutorService
提供了理想的框架。
在您的主对象中,您可以创建服务的实例(具有您想要的线程数),然后在生成一项工作时,将其提交给服务,服务将从中选择下一个可用的线程。池并执行它。
如果您依赖于了解特定工作是否已完成,则可以使用类似CountDownLatch
来跟踪线程何时完成其工作。 我的观点是,这种活动有很多现有的框架,不需要再次经历痛苦......
没有任何代码,给你一个确切的解决方案有点困难。 这听起来像是在描述生产者/消费者模式,在这种模式中,您为一组工作线程提供了一些任务,当它们完成时,您会给它们更多。
这是一个网页 ,可以很好地描述要做什么。
另请查看ExecutorService ,它允许您提交Runnables并执行它们。
一个简单的解决方案是让主线程休眠:
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.
}
主线程启动工人,定期醒来检查他们是否已经终止。 由于主线程是一个“仲裁者”,它可能不应该只是被其中一个孩子复活而死。
参考
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.