java - 有没有其他方法可以在不使用下面代码中的 Join 的情况下启用多线程

标签 java multithreading

目前我正在使用 join() 加入我当前的线程。据我所知 join 会使其成为简单的顺序代码。我想在多线程中做到这一点。

public class A {

private static final Logger logger = LoggerFactory.getLogger(A.class);

@Value("${query.interval}")
private String queryInterval;

private Set<B> missingKeys = new HashSet<>();
private Map<E, String> erroredKeys;

public Map<B, Collection<Product>> methodA(
        List<B> searchKeyList) {

    long startTime = System.currentTimeMillis();        
    missingKeys = new HashSet<>();
    erroredKeys = new HashMap<>();
    int size = searchKeyList.size();
    int threadNumber = 0;
    int startIndex = 0;
    int endIndex = 0;
    List<C> c = new ArrayList<>();

    int qrySize = Integer.parseInt(queryInterval);

    logger.info("Size of searchKeyList [{}] of instrument look up", new Object[] { searchKeyList.size() });
    for (; threadNumber < size / rdsQrySize; threadNumber++) {

        startIndex = threadNumber * rdsQrySize;
        endIndex = startIndex + rdsQrySize;

        logger.debug("Creating thread for Instrument LookUp");
        c = createThread(threadNumber, startIndex, endIndex,
                searchKeyList, c);

    }

    if (size % rdsQrySize != 0) {

        startIndex = threadNumber * rdsQrySize;
        endIndex = startIndex + size % rdsQrySize;

        logger.debug("Creating EXTRA thread for Instrument LookUp");

        c = createThread(requestor, businessLine, resolutionEnum, threadNumber, startIndex, endIndex,
                searchKeyList, c);

    }

    // Here I don't want to use join. I am looking for any other way to do this
    // to make my code run in multithreaded way

    for (C lookUpThread : c) {
        try {
            lookUpThread.join();
        } catch (InterruptedException e) {

        }
    }

    Map<B, Collection<Product>> responseDataList = new HashMap<>();
    for (C lookUpThread : c) {

        Map<B, Collection<Product>> instrumentResponseData = lookUpThread.getInstrumentResponse()
                .getFoundData();
        missingKeys.addAll(lookUpThread.getInstrumentResponse().getMissingKeys());
        erroredKeys.putAll(lookUpThread.getInstrumentResponse().getErroredKeys());
        responseDataList.putAll(instrumentResponseData);

    }

    long stopTime = System.currentTimeMillis();

    logger.info(
            "[{}] milliseconds taken to fetch [{}] instruments from RDS divided in [{}] threads  ",
            new Object[] { stopTime - startTime,size,  c.size() });

    return responseDataList;

}

private List<C> createThread(int threadNumber, int startIndex, int endIndex,
        List<B> searchKeyList, List<C> c) {

    List<B> searchKeys = new ArrayList<>();
    for (; startIndex < endIndex; startIndex++) {
        searchKeys.add(searchKeyList.get(startIndex));
    }

    ProductRequest<B> request = new ProductRequest<>(
            searchKeys);

    logger.info("Creating  thread no [{}] for Instrument LookUp", new Object[]{threadNumber});
    C lookUpThread = new C("RDS Instrument Thread - " + threadNumber);
    lookUpThread.setRequest(request);
    lookUpThread.start();

    c.add(lookUpThread);


    return c;
}

public Set<B> getMissingKeys() {
    return missingKeys;
}

public void setMissingKeys(Set<B> missingKeys) {
    this.missingKeys = missingKeys;
}

public Map<E, String> getErroredKeys() {
    return erroredKeys;
}

public void setErroredKeys(Map<E, String> erroredKeys) {
    this.erroredKeys = erroredKeys;
}

// Inner class for thread


private class C extends Thread {

    ClientResponse<B, Product, E> instrumentResponse = null;
    ProductRequest<B> request = null;

    C(String name) {
        super.setName(name);
    }

    public void run() {
        long startTime = System.currentTimeMillis();
        instrumentResponse = rdsDao.getByKey(request);
        long stopTime = System.currentTimeMillis();

        logger.info("RDS responded in [{}] milliseconds for thread [{}] while Instrument Lookup",
                new Object[] { stopTime - startTime, super.getName() });

    }

    public void setInstrumentResponse(
            ClientResponse<B, Product, E> instrumentResponse) {
        this.instrumentResponse = instrumentResponse;
    }

    public ClientResponse<B, Product, E> getInstrumentResponse() {
        return instrumentResponse;
    }

    public void setRequest(ProductRequest<B> request) {
        this.request = request;
    }

    public ProductRequest<B> getRequest() {
        return request;
    }

}
}

最佳答案

您的代码是并发运行的(而不是像您提到的那样按顺序运行)。

ThreadT.join() 将使当前线程等待 ThreadT 完成。

当您生成多个线程并加入主线程时,那些非主线程仍将同时运行(当您在 createThread()< 中调用 Thread.start() 时)/)。

如果您没有像上面那样加入非主线程,那么您的主线程/方法将在其他非主线程完成之前完成,我想这对您来说是不希望的。

关于java - 有没有其他方法可以在不使用下面代码中的 Join 的情况下启用多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37659718/

相关文章:

c# - Task.Run 如何受 CPU 内核限制?

c# - .Net 中的负载测试应该遵循哪种方式?

java - 热点默认最大堆大小

java - JUNIT 5 报告自动折叠

java - 设置布局管理器

c# - System.threading.timer 在 Windows 服务中不工作

iOS - 同时发送和接收数据

java - 如何实现异步计算?

java - 基本 Java 文件服务器

java - CAS 中平面文件身份验证的自定义属性