This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Threads and Synchronization and the fly likes clarification needed Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "clarification needed" Watch "clarification needed" New topic
Author

clarification needed

Joel Carklin
Greenhorn

Joined: Jun 15, 2001
Posts: 28
Hi, I'm new to Java and programming generally, if the answers to this question are already to be found somewhere I'd appreciate a point in the right direction:
Just want to check my understanding is correct here:
If an objects method is synchronized, it means that only one object can call
the method at a time, other objects wishing to use that specific method must
wait till the object using it is either finished with it or is waiting for
some value to be changed before continuing....
If a block of code in an object is synchronized with the form:
Synchronized(object o){
...............
}
this means only the object specified in the brackets has access to the block
of code - other objects cannot touch it? This form of synchronization
confuses me a little.
also confusing me is this:
one thread can contain more than one object. If one object in the thread
calls a synchronized method of another object in another thread, do the
other objects in the calling thread have access to that method? or, do other
methods in the calling object have access to that method...Know what I mean?
Thanks in advance
Joel

Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
Joel;
Here's Synchronization 101 in a nutshell:
In Java, every object can act as a monitor. A monitor is an entity with a single lock and a wait set. Only one thread can hold a given monitor's lock at any given time. Any other threads which need the lock sit in the wait set until the lock becomes available.
Threads must grab locks in order to execute synchronized code. There are two forms of the <code>synchronized</code> keyword, but one is just a convenient shorthand for a common usage of the other. Most authors make the mistake of teaching the shorthand version first and give insufficient treatment to the real one. The important form to understand is the synchronized statement, i.e.
<pre><code>
synchronized (anObject) {
...
}
</code></pre>When a thread attempts to execute this code, it first must obtain the lock of the monitor <code>anObject</code>. If the lock isn't available, the thread goes to the monitor's wait set.
The other form (<code>synchronized methodName() {...}</code>) is equivalent to
<pre><code>
methodName() {
synchronized (this) {
...
}
}
</code></pre>It's a useful shorthand because the most common form of synchronization involves an object protecting its own internal data from concurrent modification by more than one thread.
That's really all there is to it. It looks like some other issues have gotten bound up in your questions, though, so I'll take a stab at them and try not to add any confusion.
1. Yes, only one thread can call a synchronized method at one time. Furthermore, if thread A is in a synchronized method of an object, then no other thread can call any other synchronized method of that object either. Remember, when a method is sync'ed it means that the body of the method is sync'ed on <code>this</code>, the object itself. Since thread A holds the object's lock, no other thread can access sync'ed methods of that object.
2. No. For the sync'ed statement <code>synchronized (anObject) {...}</code> (all the code within the <code>{...}</code> is considered a single statement) the object <code>anObject</code> is the monitor whose lock must be obtained by the thread attempting to execute the statement. Any method of any object might be trying to execute this statement. What's important is that only the thread that holds the lock belonging to <code>anObject</code> can execute the statement.
3. The term "thread" is short for "thread of control". Think of a thread as a sequence of Java statements one after the other; a single path of execution through a program. You might not know the exact sequence until runtime due to branching, loops, and the like, but you get the idea. Threads of control don't contain objects - they're different concepts, but related by the fact that Java provides a <code>Thread</code> class which represents and allows you to manipulate a thread of control.
Hope this helps. Got to go, my coffee cup is empty.
jply

[This message has been edited by Jerry Pulley (edited October 02, 2000).]
Joel Carklin
Greenhorn

Joined: Jun 15, 2001
Posts: 28
Hi Jerry,
Thanks for reply, that makes sense, I think
To check though, basically:

When Object calls a synchronized Method it locks that Object (or rather that objects monitor)which contains the Method, and runs the Method. While the Method is running, no other Object can call any of the synchronized methods in the locked Object. But can call non-synchronized methods?

When a block of code is synchronized as follows:
synchronized(anObject O)
{..............body code...........;}
it means that the calling Object has now locked aObject O, and has access to all its avalable methods, both synchronized and non-synchronized for the duration of the body code. Once that bit of code is complete other objects may lock aObject O.
Just 2 questions, say you have an Object x
In a main method or another thread is the code:
synchronized(x)
{..............body code...........;}
can we assume that a) x is a thread; and b) x contains synchronized methods; and c) the body code above calls one or more of these methods as in x.aMethod( ){..}
Am I getting warm here or am I still way off track?
Thanks
Joel
Rahul Mahindrakar
Ranch Hand

Joined: Jul 28, 2000
Posts: 1849
can we assume that
a) x is a thread;
No you can't. x can be a thread Object but it can be any other object
b) x contains synchronized methods;
It may or may not contain any synchronized methods.
c) the body code above calls one or more of these methods as in x.aMethod( ){..}
Again , It is based on the program logic followed. you may or may not access x 's methods.
Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
Joel;
You're still kind of off track, but I think I can see where. You keep saying things like "an object holds another object's lock..." and "if an object is calling another object's synchronized method can another object call another sync'ed method of that same object..."; these statements indicate your misunderstanding. Here's the clarification you need: Objects don't hold locks, threads hold locks. An object doesn't enter a method body, a thread enters a method body.
It makes no sense to say something like the calling Object has now locked aObject O, and has access to all its avalable methods. It does make sense to say "the calling thread now holds anObject's lock, and so has access to any code synchronized on that object".
Joel Carklin
Greenhorn

Joined: Jun 15, 2001
Posts: 28
Jerry, Rahul, thanks;
I am obviously getting confused between objects and threads. In one sense a thread is an Object(in that it is a sub class of Object), but maybe I need to differentiate between objects which are 'things' which contain variables, methods etc, and threads which are processes, i.e the actual running of the methods in a
particular order as described in the run( ) method of the thread's object? The thread 'Object', then just *represents*
the thread, how it will it run, when it runs, but is not actually the thread itself. You said thread is 'thread of control'it is easier for me to think of thread as being 'a thread of execution' is this correct? The thread is executing the
code. Now, if the thread is executing a piece of code, say defined in a main method of a class(can we call it the main thread?), it creates an object x ( new x) and then executes one of x's methods x.aMethod( ). aMethod is declared as being
synchronized (in the class upon which object x is based). If no other threads are processing synchronized code found in object x, then the main thread is free to execute the required method and then go back to continue with the code found after the call to x.aMethod. If, however, another thread is executing a piece of synchronised code(even if it is a different piece of code) found in Object x then the main thread must wait. (we'll have to assume then that the main thread created some other threads, before or after creating object x, all of which have access to x)
???
In this context, the code synchronized(this){.....} makes sense to me; it is saying 'this' object is synchronized;
only one thread may access the code in the curly braces at a time. Other code in 'this' object may also be part
of 'this' objects synchronization and will also be declared so by the synchronized(this){.....} modifier. All the synchronized
bits of code in 'this' object are synchronised to each other, thus a thread executing one block of code locks 'all' the
bits of synchronized code from other threads of execution. Is this correct?
Still confuzeld by the following:
If I say synchronized(x){....}, am I saying 'Object x' is now synchronized? Is the thread saying:
while I am executing the following code no other thread of execution may access any synchronized code found in Object x?
or equally, the thread is saying, in order to execute following code, I must have the access to Object x...
But object x might not have any synchronized code according to my wrong assumptions in last post.
Basically my wrong assumptions were that only a thread can have synchronized code - wrong, any object can have synchronized code in it. But what would be the point of the code
synchronized(x){.....}, if
a) x does not contain any synchronized methods, or b) the program logic found in the curly braces doesn't access any of x 's methods.
still confused here, but I do feel like it is getting clearer,
promise; your assistance is not in vain. Thanks.
I need a drink, what the hell kind of saloon is this anyway? Bartender.....
Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
Joel;
You seem to be willing to work at this, so I'll hang in there too. We're getting there. I'm afraid this'll be a long post as I'm going to insert and comment on your last message.
...differentiate between objects ... and threads which are processes... Absolutely correct. In fact, a thread is often referred to as a "lightweight process".
...think of thread as being 'a thread of execution' is this correct? The thread is executing the code. Correct again.
Now, if the thread is executing a piece of code...aMethod is declared as being synchronized...If, however, another thread is executing a piece of synchronised code(even if it is a different piece of code) found in Object x then the main thread must wait. Not necessarily. It depends on what objects the two pieces of code in x are synchronized on. If they're sync'ed on the same object, then what you said is true. If they're sync'ed on different objects, then each thread may access the different code blocks in parallel, provided each holds the appropriate lock for its code block.
Here's an important point - objects aren't sync'ed, code blocks are. Some authors use the phrase "synchronized class" to denote a class whose public methods are all declared with the <code>synchronized</code> keyword; to my mind this is incorrect and misleading. The only thing you can sync is a block of code. To "sync a code block" means "to require that the lock belonging to a (perhaps implicitly) specified object be obtained before entry into the block." Note that the object whose lock is required is not necessarily the object whose class contains the code block.
...the code synchronized(this){.....} ...is saying...only one thread may access the code in the curly braces at a time. True, but only because only one thread can hold the lock belonging to <code>this</code> at a time, not because only one thread can execute code in the object. Read on. All the synchronized bits of code in 'this' object are synchronised to each other... No. Two sync'ed code blocks in the same object are not mutually exclusive just because they're in the same object. This seems to be a point of confusion, so I'll give a pair of counterexamples:<pre><code>
class Cueball {}
class Poolstick {}
class A {
private Cueball cueball;
private Poolstick stick;
A( Cueball c, Poolstick p ) {
cueball = c;
stick = p
}
void methodOne {
...
synchronized (cueball) {
...
}
}
void methodTwo {
...
synchronized (stick) {
...
}
}
}</code></pre>
In this example, one thread could execute the sync'ed code in <code>methodOne</code> and another thread could execute the code in <code>methodTwo</code>, in parallel (or even at the same time, if there are multiple CPU's). The fact that the two code blocks are in the same object is of no importance; they could even be in the same method. What's important is that the two blocks are sync'ed on different objects. Compare that situation with this one:<pre><code>
class Cueball {}
class PlayerOne {
private Cueball cueball;
PlayerOne( Cueball c ) {
cueball = c;
}
void oneShoots() {
synchronized (cueball) {
...
}
}
}
class PlayerTwo {
private Cueball cueball;
PlayerTwo( Cueball c ) {
cueball = c;
}
void twoShoots() {
synchronized (cueball) {
...
}
}
}
public class PoolGame {
public static void main( String[] args ) {
Cueball theBall = new Cueball();
PlayerOne p1 = new PlayerOne( theBall );
PlayerTwo p2 = new PlayerTwo( theBall );
//code to create and start threads goes here...
}
}</code></pre>
In this example, suppose one thread tried to execute <code>PlayerOne.oneShoots()</code> and another thread <code>PlayerTwo.twoShoots()</code>. Even though the sync'ed blocks are in different objects, the two threads could not proceed in parallel; one would have to wait. This is because the two blocks are sync'ed on the same object, which has only one lock.
The important point to take from this post (sorry about the length, guys) is that synchronization means to protect a block of code from concurrent access by requiring threads to obtain a unique lock before entering the block.
OK, Joel, I've put in my time, now you get to work. Rewrite the pool player example so it works. Each player needs the cueball to shoot. Start two threads, one per player. The <code>run()</code> methods should do nothing but shoot and print a message, then notify the monitor (the cueball) that they've shot, then wait. You can let them shoot forever, or you can make <code>run()</code> exit after some number of shots. Post your program within the next couple of days; if you're having trouble just post what you've got.
Enjoy,
jply

[This message has been edited by Jerry Pulley (edited October 03, 2000).]
Joel Carklin
Greenhorn

Joined: Jun 15, 2001
Posts: 28
/*Well Jerry, thanks a lot (grumble, grumble, I mean homework??)
I've given it a try, now I am not sure if this is what you wanted, but it seems to work.
I'm sure there is probably an easier way to achieve what this program does??
But it was a good idea, cause it did clear up the issues that were confusing me:
(I think) It took me a while to figure out where to put the wait's and notify's and I'm
still not sure if I got it right...I had to put a Time limit in PlayerTwo's wait( ) cause otherwise
the program doesn't end: the for loop in PlayerOne comes to an end so the final notify( ) is never
reached and PlayerTwo just keeps on waiting. I'm sure I've done something wrong there and
there is an easier way....? One question though: if a Number of threads are in wait( ) mode and all are
waiting for the same objects monitor to notify them, can you specify which Thread is to be notified
or is it just a free for all? Thinkin about it, I suppose you could give a Thread a higher priority if you
wanted to make sure it runs before the other? hmm anyway I'm off the topic: This is my code.
I hope it is what you want...Go easy on me, it's (almost) my first time you know....
*/

[This message has been edited by Joel Carklin (edited October 05, 2000).]
Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
Joel;
Outstanding. It works, it's correct, and it's more than I honestly expected. Bartender, a round for the gentleman.
Let's get some more mileage out of this. We can nudge this towards perfect form in a couple of iterations.
1) I'm not a style Nazi (really) but read Code Conventions for the JavaTM Programming Language. Sun has been kind enough to resolve all stylistic debates in advance by laying down guidelines. Don't pay any attention to the style guidelines on this site, they've got lots of antiquated rules and a few things that are just bad advice. (There. That should generate some mail...)
2) You got the <code>notify</code> and <code>wait</code> calls on the right object. That's how it's done; it's the core of multithreaded programming. These methods are called on the monitor object, and most often the best choice for the monitor is the object needing protection from concurrent access. But it's usually a bad idea to have synchronized code directly in the <code>run</code> method (more mail...). Move all the synchronization and the <code>wait</code> and <code>notify</code> calls into the <code>XXXshoots</code> methods. <code>run</code> should contain nothing more than a loop that calls <code>XXXshoots</code>.
One concrete benefit of this change - it should allow the program to exit without resorting to a timed wait, as <code>run</code> can go ahead and exit when the player is done shooting. You can avoid lots of complications by keeping sync'ed code out of <code>run</code>.
3) The <code>PlayerXXX</code> classes are so similar that they should be just one class with a name field. I know, my original example was the starting point, but it's time to refactor. This will, of course, affect the class and method names.
4) Exceptions have a <code>toString</code> method that gets called when you use the exception object itself as the argument to <code>println</code>. It's best to say <code>println( e )</code>.
About your questions - no, there's no way to specify which thread in a wait set will wake when you call <code>notify</code>. Some VM's respect priorities to different degrees in this regard, and some not at all. The way to handle that is through careful choice of monitor objects. You could call <code>notifyAll</code> which wakes every thread in the wait set, but only one gets the lock and the others wait again anyway.
About priorities - don't mess with them for now. Most authorities agree that the best you can do with priorities is final performance tweaking of a near-finished product.
Again, good work. Seriously, I'm gonna go have a beer.
jply
P.S. Now that I think about it, you still might have to take some extra step to ensure that the program exits. I'll have to think about that one.
[This message has been edited by Jerry Pulley (edited October 05, 2000).]
Joel Carklin
Greenhorn

Joined: Jun 15, 2001
Posts: 28
Jerry,
Thanks for all your time and energy in assisting me - and I thought I just needed clarification! I do have a much better understanding now, and your last message has given my confidence a boost
So, cheers
I'll rewrite the program taking into account the extra guidelines you've just given me...
and next round is on me...
Joel
 
 
subject: clarification needed
 
Similar Threads
Synchronized method and Sychronized block
Lock for whole object? or only synchronized block?
thread doubt
Difference between synchronized method and synchrozed block
Synchronized blocks