-1

I am writing application using multi threads to count number of char inside txt file. File contains 10 000 000 chars. 10 000 rows and 1 000 columns.

EDITED
About first part of the question: Prevoius questions was about threads, I used a thread.join(); in wrong way.

Second part: Could you help me improve the performance and safety? Here is my code (Use of the Semaphore is required):

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

}

Every element inside LinkedList contains one row (1 000 chars).

Serafins
  • 1,237
  • 1
  • 17
  • 36
  • why don't you try with 1,2,4 threads. And are you sure you are running all the threads in parallel? `first.join()` is executed before `second.start()` – arunmoezhi Oct 15 '14 at 21:03
  • Have you tried [`Fork/Join`](http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html) approach? – PM 77-1 Oct 15 '14 at 21:07
  • Besides that your hashmap implemantation is choosen wrongly - it's not thread safe and your usage of atomicinteger is bad. – Tomasz Szuba Oct 15 '14 at 21:08
  • @TomaszSzuba how can I implement it correctly? – Serafins Oct 15 '14 at 21:10
  • Please be thoughtful when editing your question. Don't change it so that it no longer matches its title or so that the answers no longer fit. Other people may have the same question that you had, and they may find your question and its answers. We want your _original_ question and the answers to still make sense when that happens. – Solomon Slow Oct 15 '14 at 22:00

1 Answers1

4

Your code does absolutely no multithreading. Thread.join means wait until that thread has finished executing, then continue the current thread of execution. Right now, your code is executing each thread serially. You want to interleave your calls to start and join.

Thread first = new Thread(calculate);
Thread third = new Thread(calculate);
Thread second = new Thread(calculate);

first.start();
second.start();
third.start();

first.join();
second.join();
third.join();
Joshua
  • 2,431
  • 15
  • 23