1

I was asked this question on a exam to count words using multithreading. There are many ways of doing the above task. Producer/consumer with sync, others without sync. What I stumbled upon is using static variables to keep total count of words across all threads. I want to count total words across all files. I wrote this code and expected to not work because static variables are not thread safe. My question if static variables are not thread safe then why is the below code working.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class WordCount implements Runnable {

    String fileName;
    static int totalCount = 0;
    static int numThreads = 0;

    public WordCount(String[] files) {

        for (String file : files) {

            new Thread(this, file).start();
        }

    }

    public void run() {

        int count = 0;
        try {
            Scanner in = new Scanner(new File(Thread.currentThread().getName()));

            while (in.hasNext()) {
                in.next();
                count++;
            }

            System.out.println(Thread.currentThread().getName() + ": " + count);
            totalCount += count;
            numThreads++;
            totalCount();
        } catch (FileNotFoundException e) {
            System.out.println(Thread.currentThread().getName() + ": Not Found");
        }

    }

    public void totalCount() {

        if (numThreads == 3) {
            System.out.println("total: " + totalCount);
        }
    }

    public int getTotalWords() {

        return totalCount;
    }
}
indersingh
  • 163
  • 2
  • 9
  • 1
    private AtomicInteger integer = new AtomicInteger() ftw – AnthonyJClink Apr 28 '14 at 17:34
  • 1
    static int variables would be a schoolbook example of something that is not thread safe. See these other threads: http://stackoverflow.com/questions/8190290/is-a-static-counter-thread-safe-in-multithreaded-application?rq=1 http://stackoverflow.com/questions/4934913/are-static-variables-shared-between-threads?rq=1 – eis Apr 28 '14 at 17:35
  • I know they are not but can anybody tell him why the above code is working. I have to prove a point to my friend.... – indersingh Apr 28 '14 at 17:37
  • What is thread safety? – Sotirios Delimanolis Apr 28 '14 at 17:40
  • the code in your question doesn't do anything that would brake when a variable is not thread safe. You'd need proper code to demonstrate that. – eis Apr 28 '14 at 17:41
  • 3
    Not being thread safe does not imply that code will not compile, run, or work. Thread safety only implies whether or not there is a possibility that multiple threads could modify the same value at the same time. – user3507600 Apr 28 '14 at 17:42
  • when the increment happens, doesn't that break thread safety. From what point do we increment. Or it doesn't matter because we are incrementing. I am leaning towards this understanding that because we are incrementing the thread safety is not issue. But I don't fully agree to that too – indersingh Apr 28 '14 at 17:44
  • 1
    Look up Race conditions. It is possible it will run correctly and it will compile, but doesn't mean it is guaranteed to run correctly. –  Apr 28 '14 at 17:44
  • I know what thread safety is, one will not get consistent answers if the resource is shared... – indersingh Apr 28 '14 at 17:45

2 Answers2

2

Not thread safe doesn't mean won't work ever. It means won't always work as expected. With your example you could change numThreads or totalCount but before they get printed those variables are updated by another thread. You should avoid sharing non-final variables between threads and if you can't you should use synchronized to force threads to line up to use variables. But, synchronized isn't a cure-all so you still need to pay attention to what you're doing and why.

crownjewel82
  • 437
  • 2
  • 12
0

I wouldnt think so.. since they are static

for int primitives, you will need to wrap them within a "synchronized" method or block.

Nemothefish
  • 47
  • 10
  • I know that too, but need to prove why the above code should not work... – indersingh Apr 28 '14 at 17:40
  • The best analogy I can think off is that static means the variable is in a fixed location in memory, but a non static variable can be put anywhere in memory, when you sychronise a block of code that whole section is taken from memory and processed, with a static variable, there is a good chance that the variable is not in that static block, and therefore it is not safe... – Nemothefish Apr 30 '14 at 11:55