Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid creating Thread hostile classes in Java

In effective java 2nd Edition Item 70 Josh Bloch explained about thread hostile classes

This class is not safe for concurrent use even if all method invocations are surrounded by external synchronization. Thread hostility usually results from modifying static data without synchronization

Can Someone explain me with example how it's impossible to achieve thread safety by external synchronization if the class modifies shared static data without internal synchronization?

like image 504
Arghya Sadhu Avatar asked Oct 26 '15 08:10

Arghya Sadhu


2 Answers

The citation assumes the synchronization of every call to the class method on the same object instance. For example, consider the following class:

public class Test {
    private Set<String> set = new TreeSet<>();

    public void add(String s) {
        set.add(s);
    }
}

While it's not thread-safe, you can safely call the add method this way:

public void safeAdd(Test t, String s) {
    synchronized(t) {
        t.add(s);
    }
}

If safeAdd is called from multiple threads with the same t, they will be mutually exclusive. If the different t is used, it's also fine as independent objects are updated.

However consider that we declare the set as static:

private static Set<String> set = new TreeSet<>();

This way even different Test objects access the shared collection. So in this case the synchronization on Test instances will not help as the same set may still be modified concurrently from different Test instances which may result in data loss, random exception, infinite loop or whatever. So such class would be thread-hostile.

like image 106
Tagir Valeev Avatar answered Oct 05 '22 20:10

Tagir Valeev


Can Someone explain me with example how it's impossible to achieve thread safety by external synchronization if the class modifies shared static data without internal synchronization?

It's not impossible. If the class has methods that access global (i.e., static) data, then you can achieve thread-safety by synchronizing on a global lock.

But forcing the caller to synchronize threads on one global lock still is thread-hostile. A big global lock can be a serious bottleneck in a multi-threaded application. What the author wants you to do is design your class so that it would be sufficient for the client to use a separate lock for each instance of the class.

like image 25
Solomon Slow Avatar answered Oct 05 '22 20:10

Solomon Slow