是否可以使用多线程而不需要一遍又一遍地创建线程?

2024-04-17

首先,再次感谢所有已经回答我问题的人。我不是一个经验丰富的程序员,这是我第一次体验多线程。

我有一个与我的问题非常相似的例子。我希望这可以缓解我们的情况。

public class ThreadMeasuring {
private static final int TASK_TIME = 1; //microseconds
private static class Batch implements Runnable {
    CountDownLatch countDown;
    public Batch(CountDownLatch countDown) {
        this.countDown = countDown;
    }

    @Override
    public void run() {         
        long t0 =System.nanoTime();
        long t = 0;
        while(t<TASK_TIME*1e6){ t = System.nanoTime() - t0; }

        if(countDown!=null) countDown.countDown();
    }
}

public static void main(String[] args) {
    ThreadFactory threadFactory = new ThreadFactory() {
        int counter = 1;
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "Executor thread " + (counter++));
            return t;
        }
    };

  // the total duty to be divided in tasks is fixed (problem dependent). 
  // Increase ntasks will mean decrease the task time proportionally. 
  // 4 Is an arbitrary example.
  // This tasks will be executed thousands of times, inside a loop alternating 
  // with serial processing that needs their result and prepare the next ones.
    int ntasks = 4; 
    int nthreads = 2;
    int ncores = Runtime.getRuntime().availableProcessors();
    if (nthreads<ncores) ncores = nthreads;     

    Batch serial = new Batch(null);
    long serialTime = System.nanoTime();
    serial.run();
    serialTime = System.nanoTime() - serialTime;

    ExecutorService executor = Executors.newFixedThreadPool( nthreads, threadFactory );
    CountDownLatch countDown = new CountDownLatch(ntasks);

    ArrayList<Batch> batches = new ArrayList<Batch>();
    for (int i = 0; i < ntasks; i++) {
        batches.add(new Batch(countDown));
    }

    long start = System.nanoTime();
    for (Batch r : batches){
        executor.execute(r);
    }

    // wait for all threads to finish their task
    try {
        countDown.await();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long tmeasured = (System.nanoTime() - start);

    System.out.println("Task time= " + TASK_TIME + " ms");
    System.out.println("Number of tasks= " + ntasks);
    System.out.println("Number of threads= " + nthreads);
    System.out.println("Number of cores= " + ncores);
    System.out.println("Measured time= " + tmeasured);
    System.out.println("Theoretical serial time= " + TASK_TIME*1000000*ntasks);
    System.out.println("Theoretical parallel time= " + (TASK_TIME*1000000*ntasks)/ncores);
    System.out.println("Speedup= " + (serialTime*ntasks)/(double)tmeasured);

    executor.shutdown();
}
 }

每个批次不进行计算,而是等待某个给定时间。该程序计算speedup,理论上总是 2,但可能会小于 1(实际上是减速)如果“TASK_TIME”很小。

我的计算最多需要 1 毫秒,而且通常更快。对于 1 毫秒,我发现加速大约为 30%,但在实践中,通过我的程序,我注意到减速.

这段代码的结构与我的程序非常相似,所以如果你能帮助我优化线程处理,我将非常感激。

亲切的问候。

下面是原来的问题:

Hi.

我想在我的程序上使用多线程,因为我相信它可以大大提高效率。它的运行时间大部分是由于独立计算造成的。

我的程序有数千个独立的计算(需要解决几个线性系统),但它们只是由几十个左右的小团体同时发生。每个组都需要几毫秒才能运行。在完成一组计算之后,程序必须按顺序运行一段时间,然后我必须再次求解线性系统。

实际上,可以将其视为要求解的这些独立线性系统位于迭代数千次的循环内,与取决于先前结果的顺序计算交替进行。我加速程序的想法是在并行线程中计算这些独立计算,通过将每个组划分为(我可用的处理器数量)独立计算批次。所以原则上根本不用排队。

我尝试使用FixedThreadPool和CachedThreadPool,它甚至比串行处理还要慢。每次我需要解决批次问题时,似乎都需要花费太多时间来创建新的踏板。

有没有更好的方法来处理这个问题?我使用的这些池似乎适合每个线程花费更多时间而不是数千个较小线程的情况......

谢谢! 此致!


线程池不会一遍又一遍地创建新线程。这就是为什么它们是游泳池。

您使用了多少个线程以及有多少个 CPU/核心?系统负载是什么样的(通常,当您串行执行它们时,以及当您使用池执行时)?是否涉及同步或任何类型的锁定?

并行执行的算法是否与串行执行的算法完全相同(您的描述似乎表明串行正在重用上一次迭代的一些结果)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以使用多线程而不需要一遍又一遍地创建线程? 的相关文章

随机推荐