Java multi threading help!

agantuk

Skilled
I have an object (Person) with a single member field (String name). The only methods available in this are get and set. Now this should be implemented such that
  • two threads cannot invoke set simultaneously
  • while one thread invokes set, another cannot invoke get
  • two or more threads should be able to invoke get simultaneously

Now it is the last requirement which is making life confusing. Synchronising the whole get method would mean only one thread would be able to access it at a time. All that I can make out is get and set would need to share the same lock to meet the second condition.

Directions please! :)

This is what I have so far:

Code:
public class Person
{
          private String name;
          private final Object myLock = new Object();

          public String get() {
               synchronized (myLock) {
                     return this.name;
               }
          }

          public void setString (String in) {
               synchronized (myLock) {
                       this.name = in;
               }
           }
}

Obviously the synchronised block in get is not going to help
 
err this should work

Code:
private String name;

public String get() {

     synchronized (this.name) {

           return this.name;

     }

}

synchronized public void setString (String in) {

      this.name = in;

}
 
deathvirus_me said:
Code:
private String name;

public String get() {
     synchronized (this.name) {
           return this.name;
     }
}
synchronized public void setString (String in) {
      this.name = in;
}

OK, from what I see, this code will not block a parallel get and set since the lock being used is different in each case - get uses the member name, whereas set uses the object's intrinsic lock. Isn't it?
haraakiri said:
I didn't get it, what does the code do? Strings are immutable in Java, what's yhe point of acquiring the lock on it?
I don't think locks have got anything to do with immutability. Or am I mistaken?
 
If you are only reading a value never writing to it, then there's no chance of a race condition. So you dont need a lock. That's the reason why in multi threaded code we must prefer immutable objects. That's one of the reasons whymaome consider functional programming language better for concurrent code.

And the above code uses one lock for writing and another lock for reading, race condition exists there.

Anyway when you call get first time, you acquire a lock on name. Now you call again it will block on name. Right? That's not what you want.
 
^^ Eer things have changed quite a lot over the years ... acquiring a lock on an object happens on many different levels, particularly if every lock would mean read lock then their would be no concurrent read access to single objects, thus no place for multithreading at all. Acquiring a write lock will indirectly set a read lock in any case, thus my above example. I pretty sure "immutable" strings won't be bothering anyone in this case.

agantuk said:
OK, from what I see, this code will not block a parallel get and set since the lock being used is different in each case - get uses the member name, whereas set uses the object's intrinsic lock. Isn't it?

synchronized methods will not be executed concurrently, particularly more with the "write" lock. get() on the other hand can be called anytime, but a synchronized block would look for the lock first, and then perform the operation accordingly.

Also correct me if i am wrong, but immutable objects are always thread safe, have no synchronization issues. So using String in the code would automatically render these properties to the class, the only thing we need to do is fulfill the calling conditions. Also, correct me if i am wrong, i dont remember reading any "do not synchronize" with immutable objects ?? Infact the particular inherent properties of these objects make them a very good synchronizing points.
 
^You are confusing references with objects. String is immutable not a reference. And, I didn't understand even a single word of your reply. :ashamed: Anyway I am sure your program isn't correct.

With multi core or multiprocessor systems you need to make sure you are using references correctly and one way is use a lock. Please read "Java concurrency in practice" to understand immutable objects , volatile references etc .
 
I'm pretty sure the code is correct coz i use it quite often .. work fine for String and Integer. Also, i think u need to clear u're idea of "lock" coz unless u do that u wont understand my reply anyway .. learning terminologies are the worst way to do thing .. i rather do practical things .. try my code, generate a few thousand threads to test the 3 conditions and profile the code .. If u do find instances of concurrent read + write, and write + write u should get a good "view" of how things actually work .. And i read the book btw .. doesn't answer my question anyway ..
 
@haraakiri, @deathvirus_me Thanks to you two for the debate, I have probably ended up being confused. My understanding of locks seems to be in jeopardy after reading this :( Of course I have been through initial parts of the Java Concurrency in Practice book. I would be getting back once I am a little bit clearer on what has been mentioned in the code sample here.

PS: Strange both you guys have names that indicate end of life :p
 
^^ concurrency in practice is a bit weird .. from my exp. what i read didn't actually run the same way when i applied it. The best way to see how things work is if u learn up profiling, then profile u're code and see how the threads are actually working, how they are accessing values and all. Its very nice to visibly see things happening. Try some basic profiling tools like VisualVM and all ...
 
^ Hmm, that's interesting. I thought Java Concurrency was probably the best book I had read on multi threading. Atleast it was easy to understand compared to the other books. I will try that Visual VM thing this weekend. Weekdays don't give enough time :)
 
deathvirus_me code doesn't seems correct. It is synchronizing on two different objects. If the code calls the getter it would check the lock for name and when the setter is called it would check the lock for this. so get and set both will be allowed by concurrent threads.
 
"Java concurrency in practice" by Brian Goetz is one of the best books for concurrency. I hope atleast this is not debatable.
"Doug Lea" book being the best, in my opinion. :)
 
anupamsinha said:
deathvirus_me code doesn't seems correct. It is synchronizing on two different objects. If the code calls the getter it would check the lock for name and when the setter is called it would check the lock for this. so get and set both will be allowed by concurrent threads.
That's what I too feel looking at the code. However since he has mentioned to try it out and see the thread behaviour using Visual VM, I am holding back on confirming it. I need to install the stuff and see.
 
I doubt visual insception would be any different.

The Java Concurrency in Practice author list for the book includes people who have contributed to the language and/or have worked on concurrent programming. Surely, makes for a great read.
 
Back
Top