2017-01-06 82 views
-3

對於我們的課堂作業,我們必須將txt文件中的單詞分成n段,在啓動程序之前我們應該能夠設置這些段。然後,每個細分受衆羣都應該擁有自己的線程,這些線程會統計單詞並停止。最後,主線程應該收集所有單個字數並將它們加在一起。同時啓動多個線程

這是(部分)是我寫到目前爲止現在

​​

,雖然這可以完成的主要工作(算上在不同的線程的話,並把它們添加到總),我不知道如何只是「讓線程離開」,然後在每個線程完成其工作之後將各個字符計數加在一起。

此外,雖然這肯定是啓動多個線程,但它只打印出我有2個,或者可能是3個線程同時運行,即使我將txt分割成100個段。有沒有辦法讓它們同時運行?

+2

你的線程無所事事。你可能想開始[這裏](https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html)。 – shmosel

+0

'Thread thread = new Thread(); thread.start();'實際上沒有做任何事情 - 你創建的線程沒有可運行的目標。 – Mshnik

+0

知道它不是那麼容易。當它不是凌晨4點時,我會閱讀它。 –

回答

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(); 
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(); 
} 
+0

謝謝!這現在非常有意義。正是我想要做的。 –

0

相同的解決方案,但執行人:

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);