java 我可以将类似线程的创建封装到一个方法中吗?

2ic8powd  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(85)

我正在写一个搜索函数,它正在执行多个API调用,我想异步执行并收集它们的结果。我所有的线程及其可运行内容看起来都很相似,这让我们想知道我是否可以将这些线程封装到一个方法中,因为每个线程只有2行更改。
它看起来与此类似:

List<BookResponse> allMatches = Collections.synchronizedList(new ArrayList<>());
List<Thread> threads = new ArrayList<>();

Thread searchBookName = new Thread(() -> {
    try {
        String someParam = someMethod();
        List<BookResponse> matches = fetchMethod(someParam);
        synchronized (allMatches) {
            allMatches.addAll(matches);
        }
    } catch (Exception e) {
        throw new CustomException(e);
    }
});
threads.add(searchBookName);
searchBookName.start();

Thread searchBookContent = new Thread(() -> {
    try {
        int intParam = anyMethod();
        List<BookResponse> matches = differentFetchMethod(intParam);
        synchronized (allMatches) {
            allMatches.addAll(matches);
        }
    } catch (Exception e) {
        throw new CustomException(e);
    }
});
threads.add(searchBookContent);
searchBookContent.start();

/*
*
*
* More Threads...
*
*
*/

for (Thread search : searches) {
    search.join();
}

return new ResponseEntity<List<BookResponse>>(allMatches, HttpStatus.OK);

这些线程块占用了代码中的大量空间,并且非常重复,它们以这种模式制作,只有2个注解行发生变化:

Thread searchSomething = new Thread(() -> {
    try {
        //Always 1 method call for a param, params are different types
        //Always 1 api call giving back results
        synchronized (allMatches) {
            allMatches.addAll(matches);
        }
    } catch (Exception e) {
        throw new CustomException(e);
    }
});
threads.add(searchSomething);
searchSomething.start();

我试图想出一个接口来解决这个问题,但我最终不得不以某种方式实现这两行代码,所以我没有使代码更干净。

g6ll5ycj

g6ll5ycj1#

你没有创建或子类化线程,你应该创建Runnables(也看看Future,Callable,Executor和线程池)。

abstract class AbstractBookSearcher<ParamType> implements Runnable {
    private final ParamType searchParam;
    AbstractBookSearcher(ParamType searchParam) {
        this.searchParam = searchParam;
    }
    public void run() throws Exception {
        try {
            List<BookResponse> matches = search(searchParam);
            synchronized (allMatches) {
                allMatches.addAll(matches);
            }
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    protected abstract List<BookResponse> search(ParamType searchParam);
}

然后子类:

class BookNameSearcher extends AbstractBookSearcher<String> {
    protected abstract List<BookResponse> search(String searchParam) {
        return fetchMethod(searchParam);
    }
}

或:

class BookContentSearcher extends AbstractBookSearcher<Integer> {
    protected abstract List<BookResponse> search(Integer searchParam) {
        return differentFetchMethod(searchParam);
    }
}

然后,您可以使用自定义和类型安全的runnables启动线程,并使用您想要的搜索参数:

new Thread(new BookNameSearcher(someMethod()));
new Thread(new BookContentSearcher(anyMethod()));

相关问题