Java Thread Problem - Synchronization

From the Sun tutorial:

Synchronized methods allow a simple strategy for avoiding thread clutter and memory consistency errors: if an object is visible to more than one thread, all reads or writes to these object variables are done using synchronized methods. (Important exception: final fields that cannot be changed after the object is created can be safely read using unsynchronized methods after the object is created.) This strategy is effective, but can present sustainability issues as we will see later in this tutorial.

Q1. The above statements mean that if an object of a class is going to be shared between multiple threads, then all instance methods of that class (except for the getters of the final fields) must be synchronized, since the instance methods are process instance variables?

+2


a source to share


10 replies


To understand concurrency in Java, I recommend the invaluable Java concurrency in practice .



In response to your specific question, while synchronizing all methods is a quick and dirty way to ensure thread safety, it doesn't scale at all. Consider a lot of defamatory vector class. Each method is synchronized, and it performs horribly because iteration is still not thread-safe.

+5


a source


No. This means that synchronized methods are a way of enforcing thread safety, but they are not the only way and by themselves do not guarantee complete safety in all situations.



+3


a source


Not necessary. You can synchronize (for example, place a lock on the allocated object) the part of the method that you are accessing, for example object variables. In other cases, you can delegate the job to some internal object (s) that already handles synchronization issues.
There are many options, it all depends on the algorithm you are implementing. Though "synced" keywords are usually the simplest.

edit
There is no comprehensive tutorial, each one is unique. Learning is like learning a foreign language: it never ends :)

But there are, of course, helpful resources. In particular, there are a number of interesting articles on the Heinz Kabutz website.
http://www.javaspecialists.eu/archive/Issue152.html (see full list on page)

If other people have any links, I would be interested to see also. I find the whole topic is quite confusing (and probably the hardest part of the java core), especially since new concurrency mechanisms were introduced in java 5.

Good luck!

+2


a source


In its most general form, yes.

Objects that cannot be synchronized are not subject to.

Also, you can use separate monitors / locks for mutable instance variables (or groups) to help with liveliness. Just like syncing only the parts where the data changes, not the whole method.

+1


a source


synchronized methodName vs synchronized (object)

This is correct and this is one of the alternatives. I think it would be more efficient to synchronize access to this object and instead synchronize all its methods.

While the difference can be subtle, it would be helpful if you use the same object on the same thread

those. (using the synchronized keyword in the method)

class SomeClass {
    private int clickCount  = 0;

    public synchronized void click(){
        clickCount++;
    }
 }

      

When a class is defined like this, only one thread at a time can call the method click

.

What happens if this method is called too often in a single threaded application? You will spend extra time checking to see if this thread can acquire a lock on the object when not needed.

class Main {
    public static void main( String  [] args ) {
         SomeClass someObject = new SomeClass();
         for( int i = 0 ; i < Integer.MAX_VALUE ; i++ ) {
             someObject.click();
         }
    }
 }

      

In this case, the check to see if the thread can lock the object will be called unnecessarily Integer.MAX_VALUE

(2,147,483,647) times.

Therefore, deleting a synchronized keyword in this situation will be much faster.

So how would you do this in a multithreaded application?

You just sync the object:

synchronized ( someObject ) {
    someObject.click();
}

      

Vector vs ArrayList

As a side note, this use of (synchhonized methodName vs. syncrhonized (object)) is, by the way, one of the reasons why java.util.Vector

it is now replaced with java.util.ArrayList

. Many of the methods are Vector

synchronized.

Most of the time the list is used in a single threaded application or piece of code (i.e. the code inside jsp / servlets is executed in a single thread) and the extra synchronization of the Vector doesn't help performance.

The same happens when replacing Hashtable

withHashMap

+1


a source


Actually getters a needs to be synchronized as well, or fields need to be done volatile

. This is because when you get a value, you are probably interested in the most recent version of the value. You can see that synchronized

block semantics not only ensure that execution is atomic (for example, it ensures that only one thread executes that block at a time), but also visibility. This means that when a thread enters a block synchronized

, it invalidates its local cache, and when it exits, it dumps any variables that have changed back to main memory. volatile

variables have the same visibility semantics.

+1


a source


No. Even getters need to be in sync, unless they only have access to final fields. The reason is that, for example, when accessing a long value, there is a small change that another stream is currently writing and you are reading it, and only the first 4 bytes have been written while the other 4 bytes remain the old value.

+1


a source


Yes, it's right. All methods that modify data or access data that can be modified by another thread must be synchronized on the same monitor.

The easiest way is to mark the methods as synchronized. If these are lengthy methods, you may only want to sync those read / write parts. In this case, you define the monitor as well as wait () and notify ().

0


a source


The simple answer is yes. If a class object will be shared by multiple threads, you need to keep the getters and setters in sync to prevent data inconsistency. If all threads will have a separate copy of the object, then there is no need to synchronize methods. If your instance methods are more than just set and retrieved, you should analyze the threat of threads waiting for the getter / setter to finish.

0


a source


You can use synchronized methods, synchronized blocks, concurrency tools like Semaphore

, or if you really want to get down and dirty you can use Atomic References. Other options include declaring member variables as volatile

well as using classes such as AtomicInteger

instead Integer

.

It all depends on the situation, but there is a wide range of concurrency tools available - here are just a few.

Synchronization can result in a wait-on lock when two threads each have a lock on an object and are trying to acquire a lock on another thread object.

Synchronization also needs to be global to the class, and it is an easy mistake to forget to synchronize the method. While a thread holds a lock on an object, other threads can still access the object's unsynchronized methods.

0


a source







All Articles