How to test if static method is thread safe

时间:2016-10-20 19:33:05

标签: java multithreading static

I have the following class:

public  class MyTestThreadStatic {

    private static int myNum;

        private MyTestThreadStatic () { // private constructor
        }
        public static void setMyNum(int val) {
            myNum = val;
        }
        public static int addOne() {
            return myNum + 1;
        }

.....

code block {
//thread 1 at t0
... some code to create a thread to call static class
System.out.println("val=" + MyTestThreadStatic.addOne());
... some other code to create a thread to call static class
//thread 2 at t0
MyTestThreadStatic.setMyNum(200);
System.out.println("val=" + MyTestThreadStatic.addOne());
}

        //stack created?

At t0 (time 0), two threads call function addOne. Will this work as expected? Will it work because two stacks were created? I would want to test this and looked at Thread and Runnable, but I am not seeing a way since neither have static methods and require object instance.

2 个答案:

答案 0 :(得分:1)

You don't need to test that; it is obvious that this is not thread safe. When there is shared information, and that information is read/written in parallel, you need some way of protection.

Which is not there in your code. Thus: as soon as you have multiple threads "working" that counter in ways that can lead to different results in different scenarios, all bets are off.

If your question is: how can I write a program that shows threading issues, you can do something like:

  1. Create a method that reads that int value, and then increases it by 1
  2. Create n threads; and each one simply calls that method m times

Now you would expect that the final value of the counter should be n x m. But you should find quickly that the counter will not have that exact value in the end!

If you want to "see" such effects with the two methods that you created, you would need something like this (pseudo code example)!

public void loopUntilMismatch() {
  while (true) {
    int value = random number
    setMyNum(value);
    int increasedValue = addOne();
    if (increasedValue != value + 1) {
      print "fail ...
      exit
    }
  }

When you run that method using multiple threads, it shouldn't take long until fail is printed and your program exits.

答案 1 :(得分:1)

It's not thread safe, nor does it attempt to be.

A test cannot prove code is thread safe. It can only attempt to prove it's not thread safe.

To prove it's not thread safe you just need to rearrange the lines of code like this

System.out.println("val=" + MyTestThreadStatic.addOne()); // Thread 1

MyTestThreadStatic.setMyNum(200); // thread 2
System.out.println("val=" + MyTestThreadStatic.addOne()); // thread 2

As each thread can execute in any order you can run the code like this

MyTestThreadStatic.setMyNum(200); // thread 2
System.out.println("val=" + MyTestThreadStatic.addOne()); // Thread 1
System.out.println("val=" + MyTestThreadStatic.addOne()); // thread 2

Now both threads print the same thing.

The only way to prove code is thread safe is to understand it and determine there is no way you can get an error when multiple threads access it no matter what order the each thread is executed.