dropson
dropson

Reputation: 1121

Java synchronized keyword - Does it protect a class method from being executed at the same time?

I need some clarificaton on how the syncronized keyword works in java 6.

Using the following example class.

class Carrier {

   private String[] _collection = new String[2];

   public Carrier() {
       this._collection[0] = "abc";
       this._collection[1] = "123";
   }

   public syncronized void change(int cId) {
       Thread.sleep(3000);
       this._collection[cId] = "changed";
   }

}

Now, some place in the application, referencing the same object instance of the Carrier class, the .change() method is called, possibly at the same time.

...carrier.change(1);

...

...carrier.change(1);

Will the syncronized keyword prevent asyncronized execution of the method? Will it simply queue the call to .change(), waiting for each one to complete?

Upvotes: 2

Views: 3316

Answers (5)

Maverik
Maverik

Reputation: 2398

synchronized are used for preventing simultaneously accesses in cuncurrent programming. For example when you have to client, one that reads and another that writes:

Lock here for an exhaustive explanation.

Upvotes: 1

Bohemian
Bohemian

Reputation: 424983

Yes - the synchronized keyword prevents simultaneous execution of the method by different threads.

Note: A "class method" is a static method. An "instance method" (ie non-static) is what you have in your question.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499810

Yes, the second thread will block while the first thread is executing. That's because they both try to acquire the monitor on the same object - via this, in this case. So your change method is equivalent to:

public void change(int cId) {
    synchronized (this) {
        Thread.sleep(3000);
        this._collection[cId] = "changed";
    }
}

Personally I don't like synchronizing on "this" as it means any other code with access to the object itself could acquire the same monitor. I prefer to create an object just for locking which only code within the class has access to:

private final Object lock = new Object();

public void change(int cId) {
    synchronized (lock) {
        Thread.sleep(3000);
        this._collection[cId] = "changed";
    }
}

That will still have the same effect in terms of two threads calling change on the same object, because both threads will still be acquiring the same monitor - just the one associated with the lock-specific object.

Upvotes: 4

JB Nizet
JB Nizet

Reputation: 691635

Yes, and yes. (Note that it's synchronized, not syncronized)

Upvotes: 1

jjnguy
jjnguy

Reputation: 138864

Yes, it will prevent the two method calls from executing at the same time.

That is really what the main use of the synchronized keyword is.

When one synchronized method runs, it obtains a 'lock' on the object it is called on. That means no other synchronized code can be run on that object while that method holds the lock. Once the method is done executing, it will release the lock, and other synchronized methods can obtain a lock on that object.

Upvotes: 3

Related Questions