Я пишу приложение, используя несколько потоков, чтобы подсчитать количество символов внутри txt-файла. Файл содержит 10 000 000 символов. 10 000 рядов и 1 000 колонн.Несколько потоков медленнее, чем один
EDITED
О первой части вопроса: Prevoius вопросов был о потоках, я использовал thread.join();
в неправильном направлении.
Вторая часть: Не могли бы вы помочь мне улучшить производительность и безопасность? Вот мой код (Использование Семафор требуется):
public class MultiThread implements Runnable {
HashMap<String, AtomicInteger> asciiMap = Maps.newHashMap();
LinkedList<String> asciiLines = ReadDataFromFile.lines;
Semaphore mutex = new Semaphore(1);
AtomicInteger i = new AtomicInteger(0);
int index;
@Override
public void run() {
long actual = 0;
try {
Calculate calculate = new Calculate();
long multiStart = System.currentTimeMillis();
Thread first = new Thread(calculate);
Thread second = new Thread(calculate);
Thread third = new Thread(calculate);
first.start();
second.start();
third.start();
first.join();
second.join();
third.join();
long multiEnd = System.currentTimeMillis();
actual = multiEnd - multiStart;
} catch (InterruptedException ex) {
Logger.getLogger(MultiThread.class.getName()).log(Level.SEVERE, null, ex);
}
int sum = 0;
for (Map.Entry<String, AtomicInteger> entry : asciiMap.entrySet()) {
System.out.println("Char: " + entry.getKey() + " , number: " + entry.getValue());
sum = sum + entry.getValue().get();
}
System.out.println("Time: " + actual);
}
int increment() {
try {
mutex.acquire();
index = i.incrementAndGet();
mutex.release();
} catch (InterruptedException ex) {
Logger.getLogger(MultiThread.class.getName()).log(Level.SEVERE, null, ex);
}
return index;
}
public class Calculate implements Runnable {
public Calculate() {
}
@Override
public void run() {
while (i.get() < asciiLines.size()) {
for (String oneCharacter : asciiLines.get(i.get()).split("")) {
if (asciiMap.containsKey(oneCharacter)) {
asciiMap.replace(oneCharacter, new AtomicInteger(asciiMap.get(oneCharacter).incrementAndGet()));
} else {
asciiMap.put(oneCharacter, new AtomicInteger(1));
}
}
i = new AtomicInteger(increment());
}
}
}
}
Каждый элемент внутри LinkedList содержит одну строку (1 000 символов).
Почему бы вам не попробовать 1,2,4 нити. И вы уверены, что используете параллельные потоки? 'first.join()' выполняется до 'second.start()' – arunmoezhi
Вы пробовали ['Fork/Join'] (http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html) подход? –
Кроме того, ваша реализация hashmap выбрана неправильно - это не потокобезопасно, и ваше использование atominteger плохое. –