对于我们的类分配,我们必须通过将它分成n个段来计算txt文件中的单词数量,我们应该能够在启动程序之前设置它们。然后每个段应该获得自己的线程,该线程对单词进行计数然后停止。最后,主线程应该收集所有单个字数并将它们加在一起。
这是我到目前为止写的(部分)
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());
}
现在,虽然这可以完成主要工作(计算不同线程中的单词并将它们添加到总计中),但我不知道如何“保留线程”,然后在每个线程之后将各个单词计数添加到一起完成了它的工作。
此外,虽然这肯定会启动多个线程,但它只打印出我有2个,或者一次运行3个线程,即使我将txt拆分为100个段。有没有办法让它们同时运行?
答案 0 :(得分:1)
问题的措辞表明每个线程都有自己的计数器,所以我会声明一个线程类:
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);
}
}
并按如下方式使用:
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();
}
答案 1 :(得分:0)
您可以使用下一个代码段作为基础。
请注意,如果您在不同的线程中增加公共变量,则此操作必须是线程安全的。这就是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();
答案 2 :(得分:0)
相同的解决方案,但使用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);