gpt4 book ai didi

java - 多线程文件读取

转载 作者:行者123 更新时间:2023-11-30 03:08:37 24 4
gpt4 key购买 nike

我正在尝试用Java编写代码来通过几个线程读取文件并计算其中的单词数。每个线程应该读取不同的行。它可以很好地计算单词数(当我让 1 个线程运行时),但我的线程正在读取同一行并同时递增行计数器。我确信 read 方法中的 synchronized 关键字会修复它,但事实并非如此。我应该做什么来修复它?

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;


public class WordCounterr implements Runnable {
private static Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
private int lineCounter;
private String path;
private int tNumber;
//private final AtomicInteger whichLine = new AtomicInteger();
private static int whichLine;
private static boolean flag;

public WordCounterr(String path,int num){
lineCounter = 0;
//whichLine = 0;
flag= false;
this.path=path;
tNumber = num;
}

public void countWords(String s) throws IOException{
char[] c = s.toCharArray();
String str="";
char ch;
for(int k=0;k<c.length;k++){

ch=c[k];
if((ch>40 && ch<91) ||(ch>96 && ch<123)){
if(ch>40 && ch<91)
ch+=32;
str+=ch;
}
else if(ch==32 ||k==c.length-1){
if(str.length()>1){ //sprawdzamy czy funkcja znalazla juz
if(ht.containsKey(str)) //takie slowo
ht.put(str,ht.get(str)+1); //znalazla - powiekszamy wartosc przy kluczu
else
ht.put(str,1); //nie znalazla - dodajemy slowo do Hashtable

}
str="";
}
}
}

public synchronized void read(String path) throws IOException{
BufferedReader buf=new BufferedReader(new FileReader(path));

String linia ;
for(int i=0;i<whichLine;i++){
linia=buf.readLine();
}

if((linia=buf.readLine())!=null){
System.out.println(linia);
countWords(linia);
lineCounter++;
System.out.println("watek nr:"+tNumber+"ktora linia:"+whichLine);
whichLine++;
/*try{
Thread.sleep(100);

}catch(InterruptedException el){
System.out.println(el.toString());
}*/
} else
setFlag(true);

buf.close(); //pamietamy o zamknieciu pliku

}

public synchronized void print(){
if(getFlag()){
setFlag(false);
System.out.println(ht);
}
System.out.println("watek nr: "+tNumber+", przeanalizowano "+ lineCounter+ "linii tekstu");
}

public void setFlag(boolean val){
flag=val;
}

public boolean getFlag(){
return flag;
}

@Override
public void run() {
try{

while(getFlag()==false) {
read(path);
Thread.yield(); //let other thread read
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}catch(IOException ex){
System.out.println(ex.toString());
}//catch(InterruptedException el){
// System.out.println(el.toString());
//}
print();
}

public static void main(String[] args) throws IOException, InterruptedException{
String path = args[0];
int tNum = Integer.parseInt(args[1]);

Thread[] thread = new Thread[tNum]; // tablica w?tków
for (int i = 0; i < tNum; i++){
thread[i] =new Thread(new WordCounterr(path,i));
}

for (int i = 0; i < tNum; i++)
thread[i].start();
}
}

最佳答案

synchronized 修饰符的定义如下:同一对象上的同步方法的两次调用不可能交错。

您正在每个线程中调用方法read

但是,您没有调用相同 read 方法,因为您将 WordCounterr实例传递给每个新的线程。这意味着您在不同的对象上调用该方法,而不会受到同步修饰符的影响。

要解决此问题,请尝试:

WordCounterr reader = new WordCounterr(path,0); //I changed i to 0 because it can't differentiate between threads with a simple int. This is because each Thread now references the same object.
Thread[] thread = new Thread[tNum]; // tablica w?tków
for (int i = 0; i < tNum; i++){
thread[i] =new Thread(reader);
}

而不是:

Thread[] thread = new Thread[tNum]; // tablica w?tków
for (int i = 0; i < tNum; i++){
thread[i] =new Thread(new WordCounterr(path,i));
}

我希望这有帮助:)

关于java - 多线程文件读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34146003/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com