【问题标题】:How to multithread with threads generated in a loop?如何使用循环中生成的线程进行多线程处理?
【发布时间】:2020-08-12 13:53:32
【问题描述】:

所以我正在编写代码,它将解析文件夹中的多个文本文件,收集有关它们的信息,并将该信息存放在两个静态 List 实例变量中。存储信息的顺序无关紧要,因为无论如何我都会对它进行排序。但是由于某种原因,增加线程数并不会影响速度。这是我的 run 方法和 main 方法中使用多线程的部分。

public void run() {
    parseFiles();
}
public static void main(String[] args) {
    while (filesLeft != 0) {
        Thread t = new Thread(new fileParser());
        t.start();
        try {
            t.join();
        }
        catch (InterruptedException e) {
            System.out.println("error.");
        }
}

如果需要额外的信息,我基本上有一个静态实例变量作为我需要通过的文件的数组,还有一个常量是线程数(出于测试目的手动更改)。例如,如果我有 4 个线程和 8 个文件,则对 parseFiles 的每次调用都会通过数组的下两个文件,索引由静态实例变量监视。例如,如果我有 4 个线程和 9 个文件,第一个线程解析 3 个文件,接下来解析 2 个文件,并带有类似于 filesToParse = Math.ceil(filesLeft / threadsLeft) 的语句,天花板函数中的后两个变量也是静态的。

我的代码中是否有任何错误,或者我应该只是测试带有更多单词的较大文本文件,以查看添加线程后速度下降(目前我有 5 个文本文件,每个文件有 20 多个段落,我得到大约 60-70 毫秒)。

【问题讨论】:

  • "但是由于某种原因,增加线程数并不影响速度" 你启动一个线程然后立即阻塞并等待它完成。
  • 是不是因为我在线程上调用了join?这就是我之前的想法,但是如果我取出 join() ,那么整个主类就永远不会停止运行。在某些时候,我不需要加入所有线程吗?如果它们是在 for 循环中生成的,我该怎么做?
  • 您需要先启动所有线程,然后您可以等待它们完成,因此您需要以某种方式跟踪它们。

标签: java multithreading loops


【解决方案1】:

写了一段可能有用的代码

public static void main(String[] args) {
    long startTime = System.nanoTime();

    final List<Runnable> tasks = generateTasks(NUM_TASKS);
    List<Thread> threadPool = new LinkedList<>();

    for(int i = 0; i < NUM_THREADS; i++) {
        Thread thread = new Thread(() -> {
            Runnable task = null;
            while ((task = getTask(tasks)) != null) {
                task.run();
            }
        });
        threadPool.add(thread);
        thread.start();
    }

    for(Thread thread: threadPool) {
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    long runTimeMs = (System.nanoTime() - startTime) / 1000000;
    System.out.println(String.format("Ran %d tasks with %d threads in %d ms", NUM_TASKS, NUM_THREADS, runTimeMs));
}

private static Runnable getTask(List<Runnable> tasks) {
    synchronized (tasks) {
        return tasks.isEmpty() ? null : tasks.remove(0);
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2022-01-16
    • 2019-02-27
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多