如何返回已完成线程的结果列表?

问题描述 投票:0回答:1

我已经编写了线程分解的程序。除了结果之外,测试对每种方法都有效。据我了解,我包括抛出异常的线程,但不包括完成的线程。 这是我得到的描述提示:

Thread newThread (Runnable runnable) - 创建并注册一个新线程。线程的名称应该是“-worker-n”,其中n是线程的编号。 ThreadUnion 必须监视创建的线程的执行 - 请参阅 results() 方法。

List results() - 返回已完成线程的结果列表。对于尚未完成的线程,不得返回任何结果。结果必须包含线程名称、完成执行时的时间戳以及抛出的 Throwable

我得到另一个提示,我应该使用 catch-finally 和 Runnable r 作为参数传递给 newThread,但不知道如何实现它。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadUnionImpl implements ThreadUnion{

    private final String name;
    private final AtomicInteger threadCount = new AtomicInteger(0);
    private final List<FinishedThreadResult> threadList = Collections.synchronizedList(new ArrayList<>());
    private boolean shutdownRequested = false;
    public ThreadUnionImpl(String name) {
        this.name = name;
    }
    @Override
    public int totalSize() {
        return threadCount.get();
    }

    @Override
    public int activeSize() {
        return (int)Thread.getAllStackTraces().keySet().stream()
                .filter(thread -> thread.getName().startsWith(name + "-worker-"))
                .count();
    }

    @Override
    public void shutdown() {
        shutdownRequested = true;
        Thread.getAllStackTraces().keySet().stream()
                .filter(thread -> thread.getName().startsWith(name + "-worker-"))
                .forEach(Thread::interrupt);
        Thread.getAllStackTraces().keySet().stream()
                .filter(thread -> thread.getName().startsWith(name + "-worker-"))
                .forEach(Thread::interrupt);
    }

    @Override
    public boolean isShutdown() {
        return shutdownRequested;
    }

    @Override
    public void awaitTermination() {
        Thread.getAllStackTraces().keySet().stream()
                .filter(thread -> thread.getName().startsWith(name + "-worker-"))
                .forEach(thread -> {
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
    }

    @Override
    public boolean isFinished() {
        return shutdownRequested && activeSize() == 0;
    }

    @Override
    public List<FinishedThreadResult> results() {
        return threadList;
    }

    @Override
    public Thread newThread(Runnable r) {
        if (shutdownRequested) throw new IllegalStateException();
        String threadName = this.name + "-worker-" + threadCount.getAndIncrement();
        Thread thread = new Thread(r, threadName);
        thread.setUncaughtExceptionHandler((t, e) -> {
            threadList.add(new FinishedThreadResult(t.getName(), e));
        });
        return thread;
    }
}

一个测试失败,提供响应:

org.opentest4j.AssertionFailedError:

预计:7 实际:4

java multithreading java-threads
1个回答
0
投票

为了确保在 results() 方法中包含已完成的线程,同时排除仍处于活动状态的线程,您需要更新您的实现。关键是跟踪已完成执行的线程并在调用 results() 方法时检索其结果。

您可以通过更新 newThread() 方法来实现此目的,以使用自定义 Runnable 实现来包装提供的 Runnable,该实现捕获异常并在完成时存储结果。

© www.soinside.com 2019 - 2024. All rights reserved.