synchronized methods "under the hood"

B

bob smith

How do synchronized methods work "under the hood"?

Is there some kind of byte associated with each object that acts as a semaphore?

Thanks.
 
D

Daniel Pitts

How do synchronized methods work "under the hood"?

Is there some kind of byte associated with each object that acts as a semaphore?
There is an object monitor, which does indeed act as a mutex. But there
is more to it than that. synchronized sections (which synchronize on
the same monitor) create a happens-before relationship. This includes
any cache/memory coherency that needs to happen to give that. It is
likely implementation dependent on how all that works under the hood.

A good read is Java Concurrency in Practice by Brian Goetz.

<http://virtualinfinity.net/wordpress/technical-book-recommendations/java-concurrency-in-practice/>

It looks like the official site for the book is under
construction.<http://jcip.net/>
 
J

Jan Burse

bob said:
How do synchronized methods work "under the hood"?

Is there some kind of byte associated with each object that acts as a semaphore?

Thanks.

If I remember well the synchronized keyword is mapped to two things:

- In reflection it is mapped to the SYNCHRONIZED modifier:

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/Modifier.html#SYNCHRONIZED

- In execution the invocation and return instruction is combined
with a monitor enter and monitor exit.

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.11.10

- For static methods the monitor is the class object, for non static
methods the monitor is the instance object.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.3.6

Bye
 
R

Roedy Green

How do synchronized methods work "under the hood"?

Is there some kind of byte associated with each object that acts as a semaphore?

At the hardware level these are usually handled by some sort of test
and test instruction. It tests if a byte is zero, and if it is, sets
it to 1. It locks out any other CPU or thread from interfering
between the test and set. If reports if the byte was zero to start
(in other words we successfully locked.) Test and Set is an "atomic"
operation.

The last time I peeked was in the hey days of Univac and CDC.
 
S

Sven Köhler

Am 05.03.2013 21:19, schrieb Roedy Green:
At the hardware level these are usually handled by some sort of test
and test instruction. It tests if a byte is zero, and if it is, sets
it to 1. It locks out any other CPU or thread from interfering
between the test and set. If reports if the byte was zero to start
(in other words we successfully locked.) Test and Set is an "atomic"
operation.

Such test and set methods are implemented in Java's Atomic* classes
(e.g. AtomicInteger). However, you need more than that to implement a
proper mutex. What I would call a proper mutex puts a thread to sleep,
if it cannot lock the mutex. To do that, you need to tell the kernel
that the thread is suspended. As far as I know, Linux futexes do both:
they first check whether the mutex is locked by using some atomic
test+set, and if that fails they resort to syscalls:
http://en.wikipedia.org/wiki/Futex


Regards,
Sven
 
R

Roedy Green

Such test and set methods are implemented in Java's Atomic* classes
(e.g. AtomicInteger). However, you need more than that to implement a
proper mutex. What I would call a proper mutex puts a thread to sleep,
if it cannot lock the mutex. To do that, you need to tell the kernel
that the thread is suspended

I thought he was asking about what happens at the hardware level.
Thread context switching I think is still done with software.

Back in the 1990s I wrote a package in C to allow threads that ran on
a single CPU. Threads had to be well behaved and call "have a
conscience" periodically. It was remarkably simple, just save and
restore contexts. It is quite bit more complicated when you can
interrupt threads in mid instruction or when you have multiple CPUs.
 
J

Jan Burse

Roedy said:
I thought he was asking about what happens at the hardware level.
Thread context switching I think is still done with software.

Back in the 1990s I wrote a package in C to allow threads that ran on
a single CPU. Threads had to be well behaved and call "have a
conscience" periodically. It was remarkably simple, just save and
restore contexts. It is quite bit more complicated when you can
interrupt threads in mid instruction or when you have multiple CPUs.

You can google the OpenJDK source and
find jvm_raw_lock etc.. in mutex.cpp.

The Java locking uses a combination of
atomic instructions for a fast path
and subsequent parking of threads, which
is I guess a queueing thing.

Bottomline is that locking causes some
overhead, seen for example when someone
uses Vector instead of ArrayList. But the
fast path makes it also not that expensive,
so that a certain use of locking is
tollerable.

As an alternative one can sometimes use
algorithms that use ordinary destructive
instructions (i.e. object field write) in
such a way, that reentrant operations result.
Example from String:


public int hashCode() {
if (hash == 0)
hash = .. compute hash ..
return hash;
}

In the above it could happen that more than
one thread computes the hash, if the check is
interleaved by a context switch. But it doesn't
do any harm, since String is immutable and always
the same hash is calculated.

Bye
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top