Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Threads calling static helper method

I have a web application running on Tomcat.

There are several calculations that need to be done on multiple places in the web application. Can I make those calculations static helper functions? If the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel? Or does one request have to wait until the other request finished the call?

public class Helper {
    public static void doSomething(int arg1, int arg2) {
        // do something with the args
        return val;
    }
}

if the calls run parallel: I have another helper class with static functions, but this class contains a private static member which is used in the static functions. How can I make sure that the functions are thread-safe?

public class Helper {

    private static SomeObject obj;

    public static void changeMember() {
        Helper.obj.changeValue();
    }

    public static String readMember() {
        Helper.obj.readValue();
    }

}

changeValue() and readValue() read/change the same member variable of Helper.obj. Do I have to make the whole static functions synchronized, or just the block where Helper.obj is used? If I should use a block, what object should I use to lock it?

like image 857
MarioP Avatar asked Jun 01 '11 14:06

MarioP


People also ask

Can static method be accessed by multiple threads?

A data type or static method is threadsafe if it behaves correctly when used from multiple threads, regardless of how those threads are executed, and without demanding additional coordination from the calling code.

What happens when two threads call the same static method?

Well, the two threads will run concurrently... Nothing to fear if the method is thread safe to begin with. If the static method doesn't modify the state of a common object used by these threads, then nothing wrong will happen. They both run the method at the same time.

Should a helper method be static?

This really depends. If the values your helpers operate on are primitives, then static methods are a good choice, as Péter pointed out. If they are complex, then SOLID applies, more specifically the S, the I and the D.

Can two threads execute two methods static and non-static concurrently?

Since both the objects are different hence both synchronized static and non-static method will not block each other in case of multi-threading. Both the methods will execute simultaneously.


2 Answers

can i make those calculations static helper functions? if the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel?

Yes, and yes.

do i have to make the whole static functions synchronized

That will work.

or just the block where Helper.obj is used

That will also work.

if i should use a block, what object should i use to lock it?

Use a static Object:

public class Helper {

    private static SomeObject obj;
    private static final Object mutex = new Object();

    public static void changeMember() {
        synchronized (mutex) {
            obj.changeValue();
        }
    }

    public static String readMember() {
        synchronized (mutex) {
            obj.readValue();
        }
    }
}

Ideally, though, you'd write the helper class to be immutable (stateless or otherwise) so that you just don't have to worry about thread safety.

like image 150
Matt Ball Avatar answered Sep 21 '22 15:09

Matt Ball


You should capture the calculations in a class, and create an instance of the class for each thread. What you have now is not threadsafe, as you are aware, and to make it threadsafe you will have to synchronize on the static resource/the methods that access that static resource, which will cause blocking.

Note that there are patterns to help you with this. You can use the strategy pattern (in its canonical form, the strategy must be chosen at runtime, which might or might not apply here) or a variant. Just create a class for each calculation with an execute method (and an interface that has the method), and pass a context object to execute. The context holds all the state of the calculation. One strategy instance per thread, with its context, and you shouldn't have any issues.

like image 29
hvgotcodes Avatar answered Sep 20 '22 15:09

hvgotcodes