Hello All,


I have a question related to synchronization in java; there's more like a confirmation. Let's start with the simplified version of my class:

class MyClass {

	private List<MyObject> myList = new ArrayList();

	public void addEntry(MyObject obj) {
		myList.add(obj);
	}

	public void removeEntry(MyObject obj) {
		myList.remove(obj);
	}

	public double computeAValue() {
		//
		//  Compute a value based on myList
		//
	}

	public double computeBValue() {
		//
		//  Compute a value based on myList
		//
	}
	
	......

}

I need to make the class thread safe... which means the following:
- don't let a thread add / remove entries in the underlying collection while computing values
- actually in plain english: I want to prevent any two methods being executed by different threads in the same time

For this to achieve I have the following solutions

  1. make each method sinchronized
  2. use a lock object at instance level and protect code blocks with
    method body ....
    synchronized(myLock) {
    	try {
    	
    	}
    	catch(Exception e) {
    		...
    	} 
    	finally {
    		myLock.notifyAll();
    	}
    }
    .... end method body

Solution 2 looks a little messier since I would have to store locks on the exterior of the class, but I'm sure it will work since there's a construction already used and tested.

The main question refers to synchronized keyword: would it achieve my requirement? I'm sure it won't let two threads execute the same method simultaneously, but would it apply to all synchronized method at the instance level?

The java lang specs states:

A synchronized method acquires a monitor before it executes. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.


This would suggest that my goal would be reached by making the methods synchronized.

Can you confirm this? Have you actually wrote code to teste this assumption or successfully used it in a production environment?

Thank you,
Marius

At the simplest, yes, simply make the methods synchronised as that will cause them to sync on the instance of the class.

1. Although the option 2 is better from performance point of view as YOU decide exactly which statements within the method are synch'd.
2. Even the statements that access the data from underlying storage need to be synch'd.

Well, if you don't declare the method synched, its not synched. But, if you meant, you can control which portions of the method are synched, yes. ;-)

Well, if you don't declare the method synched, its not synched. But, if you meant, you can control which portions of the method are synched, yes. ;-)

I also didn't completely get your comment (like you didn't get mine :)).
What I meant was do NOT declare the method synch'd. Inside the implementation (of the method) put synch for required statements "manually" (somethihg like what he posted in the original question).

Well, you had said that doing the sync inside the method will allow the programmer to control which methods are synched. Well, you can do that with the synchronized keyword as well. Simply do not declare the methods you do not want to be synched as synchronized. Now, if you want to be able to control, for example, that only the excution of two lines out of a hundred line method are synched, then, yes, do the synchronization inside the method. But, if you are going to synch on the current instance, and the entire (or nearly the entire) method's content will be synched, then there is no reason not to use the synchnronized keyword on the method.

Edited 5 Years Ago by masijade: n/a

Hello All,

Thank you for the answers, I guess I was overcautious on this. My understanding of synchronized (which was not complete) involved threads not executing the same synchronized method when in fact the synchronized protection spans across methods that are marked as synchronized.

NetBeans IDE along with its Profiler provides a nice visual representation of the threads and their states in real-time. I have created a project that you can find attached and couple of executions with two sets of parameters.

The execution2.txt / threads2.gif show how Worker_2 waits on adding new elements while Worker_1 is finishing the getListAsStrings() method.


All the best,
Marius

Attachments
1301927392 Worker_1 adding String_1
1301927392 Worker_2 adding String_1
1301927392 Worker_3 adding String_1
1301927392 Worker_1 added String_1
1301927392 Worker_1 adding String_2
1301927393 Worker_3 added String_1
1301927393 Worker_3 adding String_2
1301927393 Worker_2 added String_1
1301927393 Worker_2 adding String_2
1301927394 Worker_3 added String_2
1301927394 Worker_3 adding String_3
1301927394 Worker_1 added String_2
1301927394 Worker_1 adding String_3
1301927395 Worker_3 added String_3
1301927395 Worker_3 adding String_4
1301927395 Worker_2 added String_2
1301927395 Worker_2 adding String_3
1301927396 Worker_3 added String_4
1301927396 Worker_3 adding String_5
1301927396 Worker_1 added String_3
1301927396 Worker_1 adding String_4
1301927397 Worker_3 added String_5
1301927397 Worker_3 adding String_6
1301927397 Worker_2 added String_3
1301927397 Worker_2 adding String_4
1301927398 Worker_3 added String_6
1301927398 Worker_3 adding String_7
1301927398 Worker_1 added String_4
1301927398 Worker_1 adding String_5
1301927399 Worker_3 added String_7
1301927399 Worker_3 adding String_8
1301927399 Worker_2 added String_4
1301927399 Worker_2 adding String_5
1301927400 Worker_3 added String_8
1301927400 Worker_1 added String_5
Worker_3 As string: String_1 : String_1 : String_1 : String_2 : String_2 : String_3 : String_2 : String_4 : String_3 : String_5 : String_3 : String_6 : String_4 : String_7 : String_4 : String_8 : String_5 : 
1301927409 Worker_2 added String_5
1301927409 Worker_2 adding String_6
Worker_1 As string: String_1 : String_1 : String_1 : String_2 : String_2 : String_3 : String_2 : String_4 : String_3 : String_5 : String_3 : String_6 : String_4 : String_7 : String_4 : String_8 : String_5 : String_5 : 
1301927418 Worker_2 added String_6
1301927418 Worker_2 adding String_7
1301927419 Worker_2 added String_7
1301927419 Worker_2 adding String_8
1301927419 Worker_2 added String_8
1301927419 Worker_2 adding String_9
1301927420 Worker_2 added String_9
1301927420 Worker_2 adding String_10
1301927420 Worker_2 added String_10
Worker_2 As string: String_1 : String_1 : String_1 : String_2 : String_2 : String_3 : String_2 : String_4 : String_3 : String_5 : String_3 : String_6 : String_4 : String_7 : String_4 : String_8 : String_5 : String_5 : String_6 : String_7 : String_8 : String_9 : String_10 :
1301927741 Worker_1 adding String_1
1301927741 Worker_2 adding String_1
1301927741 Worker_3 adding String_1
1301927741 Worker_1 added String_1
1301927741 Worker_1 adding String_2
1301927742 Worker_1 added String_2
1301927742 Worker_1 adding String_3
1301927742 Worker_3 added String_1
1301927742 Worker_3 adding String_2
1301927743 Worker_2 added String_1
1301927743 Worker_2 adding String_2
1301927743 Worker_3 added String_2
1301927743 Worker_3 adding String_3
1301927744 Worker_1 added String_3
1301927744 Worker_1 adding String_4
1301927744 Worker_3 added String_3
1301927745 Worker_2 added String_2
1301927745 Worker_2 adding String_3
Worker_3 As string: String_1 : String_2 : String_1 : String_1 : String_2 : String_3 : String_3 : String_2 : 
1301927749 Worker_1 added String_4
1301927749 Worker_1 adding String_5
1301927750 Worker_2 added String_3
1301927750 Worker_2 adding String_4
1301927750 Worker_1 added String_5
1301927750 Worker_1 adding String_6
1301927751 Worker_2 added String_4
1301927751 Worker_2 adding String_5
1301927751 Worker_1 added String_6
1301927751 Worker_1 adding String_7
1301927752 Worker_1 added String_7
1301927752 Worker_1 adding String_8
1301927752 Worker_2 added String_5
1301927752 Worker_2 adding String_6
1301927753 Worker_1 added String_8
1301927753 Worker_1 adding String_9
1301927753 Worker_2 added String_6
1301927753 Worker_2 adding String_7
1301927754 Worker_1 added String_9
1301927754 Worker_1 adding String_10
1301927754 Worker_1 added String_10
1301927754 Worker_1 adding String_11
1301927755 Worker_2 added String_7
1301927755 Worker_2 adding String_8
1301927755 Worker_1 added String_11
1301927755 Worker_1 adding String_12
1301927756 Worker_2 added String_8
1301927756 Worker_2 adding String_9
1301927756 Worker_1 added String_12
1301927756 Worker_1 adding String_13
1301927757 Worker_1 added String_13
1301927757 Worker_1 adding String_14
1301927757 Worker_2 added String_9
1301927757 Worker_2 adding String_10
1301927758 Worker_1 added String_14
1301927758 Worker_1 adding String_15
1301927758 Worker_2 added String_10
1301927758 Worker_2 adding String_11
1301927759 Worker_1 added String_15
1301927759 Worker_1 adding String_16
1301927759 Worker_1 added String_16
1301927759 Worker_1 adding String_17
1301927760 Worker_2 added String_11
1301927760 Worker_2 adding String_12
1301927760 Worker_1 added String_17
1301927760 Worker_1 adding String_18
1301927761 Worker_2 added String_12
1301927761 Worker_2 adding String_13
1301927761 Worker_1 added String_18
1301927761 Worker_1 adding String_19
1301927762 Worker_2 added String_13
1301927762 Worker_2 adding String_14
1301927762 Worker_1 added String_19
1301927762 Worker_1 adding String_20
1301927763 Worker_2 added String_14
1301927763 Worker_2 adding String_15
1301927763 Worker_1 added String_20
1301927764 Worker_2 added String_15
1301927764 Worker_2 adding String_16
Worker_1 As string: String_1 : String_2 : String_1 : String_1 : String_2 : String_3 : String_3 : String_2 : String_4 : String_3 : String_5 : String_4 : String_6 : String_7 : String_5 : String_8 : String_6 : String_9 : String_10 : String_7 : String_11 : String_8 : String_12 : String_13 : String_9 : String_14 : String_10 : String_15 : String_16 : String_11 : String_17 : String_12 : String_18 : String_13 : String_19 : String_14 : String_20 : String_15 : 
1301927783 Worker_2 added String_16
1301927783 Worker_2 adding String_17
1301927784 Worker_2 added String_17
1301927784 Worker_2 adding String_18
1301927784 Worker_2 added String_18
1301927784 Worker_2 adding String_19
1301927785 Worker_2 added String_19
1301927785 Worker_2 adding String_20
1301927785 Worker_2 added String_20
1301927785 Worker_2 adding String_21
1301927786 Worker_2 added String_21
1301927786 Worker_2 adding String_22
1301927786 Worker_2 added String_22
1301927786 Worker_2 adding String_23
1301927787 Worker_2 added String_23
1301927787 Worker_2 adding String_24
1301927787 Worker_2 added String_24
1301927787 Worker_2 adding String_25
1301927788 Worker_2 added String_25
1301927788 Worker_2 adding String_26
1301927788 Worker_2 added String_26
1301927788 Worker_2 adding String_27
1301927789 Worker_2 added String_27
1301927789 Worker_2 adding String_28
1301927789 Worker_2 added String_28
1301927789 Worker_2 adding String_29
1301927790 Worker_2 added String_29
1301927790 Worker_2 adding String_30
1301927790 Worker_2 added String_30
Worker_2 As string: String_1 : String_2 : String_1 : String_1 : String_2 : String_3 : String_3 : String_2 : String_4 : String_3 : String_5 : String_4 : String_6 : String_7 : String_5 : String_8 : String_6 : String_9 : String_10 : String_7 : String_11 : String_8 : String_12 : String_13 : String_9 : String_14 : String_10 : String_15 : String_16 : String_11 : String_17 : String_12 : String_18 : String_13 : String_19 : String_14 : String_20 : String_15 : String_16 : String_17 : String_18 : String_19 : String_20 : String_21 : String_22 : String_23 : String_24 : String_25 : String_26 : String_27 : String_28 : String_29 : String_30 :
threads.gif 5.28 KB threads2.gif 5.2 KB

Well, you had said that doing the sync inside the method will allow the programmer to control which methods are synched. Well, you can do that with the synchronized keyword as well. Simply do not declare the methods you do not want to be synched as synchronized. Now, if you want to be able to control, for example, that only the excution of two lines out of a hundred line method are synched, then, yes, do the synchronization inside the method. But, if you are going to synch on the current instance, and the entire (or nearly the entire) method's content will be synched, then there is no reason not to use the synchnronized keyword on the method.

We're on the same page. Perhaps you read my post too quickly. I said "which statements within the method".

This article has been dead for over six months. Start a new discussion instead.