如何从另一种方法中断方法?

时间:2018-03-11 15:05:44

标签: java multithreading concurrency

我有两种方法可以同时运行。

public void bar(){
    //Do some stuff which has a result
    //If result is true, then stop foo().
}

public void foo()
{
    for (int x = 0; x <= 100; ++x)
    {
        //Do some stuff...
        //Execute bar, but don't wait for it to finish before jumping to next iteration.
    }
}

我理解它的方式,当一个方法被调用时,它被放到堆栈中,然后当方法完成时它从堆栈返回,然后程序将继续从调用方法的位置执行。

因此,如果foo()在循环期间调用bar(),它将等到bar()返回后再继续循环。

然而,我想要发生的是,当foo执行bar时,它不会等到bar完成执行之后再继续迭代;它只是通知bar()应该运行然后继续循环。

类似于线程中的run将如何运行该方法然后将其返回,但start将在新线程中启动run方法,并start方法立即返回,允许下一行代码运行。

此外,每次运行bar()时,根据结果,我希望它中断foo(),无论当前正在执行哪一行foo()。我不想在foo()方法中检查bar()的结果,但我想要这样的功能,当foo()执行时,它会被bar()的执行中断。

希望能让这个更容易理解:让我说我有两个人做任务A和B. A是foo,B是bar。

A将完成他的任务100次,但在每次执行任务后,他告诉B执行各自的任务(在每次迭代结束时调用bar()),然后继续执行下一个任务任务。

B执行任务所需的时间比执行任务需要的时间短,所以当B完成任务时,A仍将执行任务,并根据B&#39;任务,他可能告诉A停止执行他的任务。

2 个答案:

答案 0 :(得分:1)

  

但是我不想每次都要创建一个新的线程来进行bar()的新迭代。

您可以实现Thread Pool,它将为您处理线程,因此您的程序不会继续为B任务生成新线程 - 它将获取工作线程。值得考虑

BTW:How to stop a thread from another thread?应该给你一个关于如何管理线程中断的提示

编辑:你可以get active Threads references by name

Thread getThreadByName(String name) {
    // Get current Thread Group
    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    ThreadGroup parentThreadGroup;
    while ((parentThreadGroup = threadGroup.getParent()) != null) {
        threadGroup = parentThreadGroup;
    }
    // List all active Threads
    final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    int nAllocated = threadMXBean.getThreadCount();
    int n = 0;
    Thread[] threads;
    do {
        nAllocated *= 2;
        threads = new Thread[nAllocated];
        n = threadGroup.enumerate(threads, true);
    } while (n == nAllocated);
    threads = Arrays.copyOf(threads, n);
    // Get Thread by name
    for (Thread thread : threads) {
        System.out.println(thread.getName());
        if (thread.getName().equals(name)) {
            return thread;
        }
    }
    return null;
}

并从您想要的任何地方中断正在运行的线程。请记住,这是一个非常花哨的解决方案,我建议您重新考虑您的并发架构。这篇文章中有很多好的解决方案 - 试一试。

void foo() {
    Thread fooThread = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                try {
                    bar(); // Spawns barThread, but continues execution
                    Thread.sleep(2000); // foo has to return after bar, else NullPointerException is thrown
                } catch (InterruptedException e) {
                    //handle interruption
                }
            }
        }
    }, "fooThread"); // here im assigning name to fooThread
    fooThread.start();
}

void bar() {
    Thread barThread = new Thread(new Runnable() {
        @Override
        public void run() {
            // do something that interrupts foo()
            getThreadByName("fooThread").interrupt();
        }
    });

    barThread.start();
}

答案 1 :(得分:0)

我不太确定你到底想做什么。 但听起来您的问题可以通过队列来解决。

queue = Queue(max_size=n)

thread_1:
    while True:
        x = foo()
        queue.put(x)

thread_2:
    while True:
        x = queue.get()
        doSomething(x)