简体   繁体   English

同时启动多个线程

[英]start multiple threads at the same time

For our assignment for class, we have to count the amount of words in a txt file by splitting it into n segments, which we are supposed to be able to set before launching the programm.对于我们的课堂作业,我们必须通过将 txt 文件分成 n 段来计算单词的数量,我们应该能够在启动程序之前对其进行设置。 Each segment should then get its own thread, which counts the words and then stops.然后每个段应该有自己的线程,它计算单词然后停止。 At the end, the main thread should collect all the individual word counts and add them together.最后,主线程应该收集所有的单个字数并将它们加在一起。

This is (part of) what I wrote so far这是我目前所写的(部分)

for (int i = 0; i < segments; i++){
            Thread thread = new Thread();
            thread.start();
            int words = counting(stringarray[i]);
            totalwords += words;
            long nanos = ManagementFactory.getThreadMXBean().getThreadCpuTime(Thread.currentThread().getId());
            System.out.println("This Thread read " + words + " words. The total word count now is " + totalwords + 
                    ". The time it took to finish for this thread is " + nanos +".");
            System.out.println("Number of active threads from the given thread: " + Thread.activeCount());
        }

Now, while this gets the primary job done (counting the words in different threads and adding them to the total), I dont know how to just "leave the thread be" and then add the individual wordcounts together after every thread has done its job.现在,虽然这完成了主要工作(计算不同线程中的单词并将它们添加到总数中),但我不知道如何只是“保留线程”,然后在每个线程完成其工作后将各个单词计数加在一起.

Additionally, while this is definitely starting multiple threads, it only ever prints out that I have 2, or maybe 3 threads running at a time, even if I split the txt into 100 segments.此外,虽然这肯定会启动多个线程,但它只会打印出我一次运行 2 个或 3 个线程,即使我将 txt 分成 100 个段。 Is there a way to have them all run at the same time?有没有办法让它们同时运行?

The wording of the question suggest that each thread has its own counter, so I would declare a thread class:问题的措辞表明每个线程都有自己的计数器,因此我将声明一个线程类:

public class WordCounter extends Thread {
    private String text;
    private int count;

    public WordCounter(String text) {
        this.text = text;
    }

    public int getCount() {
        return count;
    }

    @Override
    public void run() {
        count = counting(text);
    }
}

and use it as follows:并按如下方式使用它:

WordCounter[] threads = new WordCounter[segments];
for (int i = 0; i < segments; ++i) {
    threads[i] = new WordCounter(stringarray[i]);
    threads[i].start();
}
int total = 0;
for (int i = 0; i < segments; ++i) {
    threads[i].join();
    total += threads[i].getCount();
}

You may use next code snippet as a basis.您可以使用下一个代码片段作为基础。 Note, that in case you increment common variable in different threads, this operation has to be thread-safe.请注意,如果您在不同线程中增加公共变量,则此操作必须是线程安全的。 That's why AtomicInteger variable is used as a counter这就是为什么AtomicInteger变量被用作计数器

final List<String> segments = new ArrayList<>();
//TODO:Fill segments ... this is up to you
//In case threads will increment same variable it has to be thread-safe
final AtomicInteger worldCount = new AtomicInteger();
//Create Thread for each segment (this is definitely not optimal)
List<Thread> workers = new ArrayList<>(segments.size());
for (int i = 0; i < segments.size(); i++) {
    final String segment = segments.get(i);
    Thread worker = new Thread(new Runnable() {
        @Override
        public void run() {
            //increment worldCount
            worldCount.addAndGet(counting(segment));
        }
    });
    workers.add(worker);
    worker.start();
}

//Wait until all Threads are finished
for (Thread worker : workers) {
    worker.join();
}
int result = worldCount.get();

Same solutions, but with Executors:相同的解决方案,但使用 Executors:

    final List<String> segments = new ArrayList<>();
    segments.add("seg1");
    segments.add("seg2");
    segments.add("seg 3");

    final AtomicInteger worldCount = new AtomicInteger();

    List<Future> workers = new ArrayList<>(segments.size());
    ExecutorService executor = Executors.newFixedThreadPool(segments.size());
    for (String segment : segments) {
        Future<Integer> worker = executor.submit(() -> worldCount.addAndGet(counting(segment)));
        workers.add(worker);
    }

    executor.shutdown();
    if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
        System.out.println("Still waiting...");
        System.exit(0);
    }

    int result = worldCount.get();

    System.out.println("result = " + result);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM