This question already has answers here:
What does 'synchronized' mean?
(17 answers)
Closed 5 years ago.
I have been trying to learn design patterns. This site uses the synchronized keyword, but I don't understand what it does.
I searched on the net and found that it is somewhat related to multi-threading and memory, but I am a mechanical engineer and don't understand what that means.
Can anybody please help me understand threads and the synchronized keyword?
There is no synchronized keyword in C++.
There is one in Java, though, where for methods it means the following two things:
It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
When a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
Similar rules apply to arbitrary blocks.
Also, I recommend learning from a peer-reviewed book, not some arbitrary non-authoritative website.
In the (Java) example
public static synchronized Singleton getInstance()
means that only one thread at a time should be able to access the getInstance() method this to avoid a racing condition.
As the commenters already pointed out, synchronized is a Java keyword.
It means that two threads cannot execute the method at the same time and the JVM takes care of enforcing that.
In C++, you will have to use some synchronization construct, like a critical section or a mutex. You can consult this.
Related
This question already has answers here:
Volatile Vs Atomic [duplicate]
(6 answers)
Closed last year.
I know the differences between both in terms of visibility and ensuring atomic access and atomic operations. But I was wondering, if for example I only needed to use Volatile, and Atomic wasn't necessary, is there an advantage (maybe memory or efficiency wise) to using just Volatile? Or can I just use Atomic instead?
The get() and set(...) methods of a Java AtomicWhatever object have exactly the same semantics as assignments to, and reads from, a volatile variable. So in effect, "Atomic" is a superset of "volatile."
The semantics are simple: If one thread assigns a volatile variable or, if it set(...)s an AtomicXxxxxx object, then whatever else it did before that assignment is guaranteed to be visible to some other thread after the other thread subsequently reads the same variable or, after it subsequently get()s from the same object.
volatile was in the language from the beginning. Atomics are newer. Some programmers will tell you that because atomics effectively are "volatile," that we don't need the volatile keyword anymore, and you should not use it. That's a matter of opinion, but if you're working on a team with other developers, it's best to use the same style and the same patterns that everybody else on the team uses.
This question already has answers here:
What does 'synchronized' mean?
(17 answers)
Closed 6 years ago.
public int synchronizedBlockGet() {
synchronized( this ) {
return i;
}
}
I have come across this code while reading some article. what is synchronized ? a class , or method or interface ? Please explain.
Synchronized or in general synchronization come when you are dealing with threads. For example, let's say there are 2 threads in you program. Both of these threads are using the same object. (Consider a scenario where one thread is writing to an ArrayList and the other one is reading from it). It those cases, we have to ensure that the other thread don't do a read or a write while a thread is writing to the list. This is because, a write to a list will consist of at least 3 steps
read from memory
modify the object(list)
write back to the memory.
In order to make sure that these threads don't intercept and will not cause inconsistencies, we use the concept of thread synchronization.
There are several ways of achieving synchronization including synchronized methods and synchronized blocks. The code you have provided is a synchronized block.
public int synchronizedBlockGet() {
synchronized( this ) {
return i;
}
}
Here what happens is, once a thread is inside the synchronizedBlockGet method, it will lock the entire object(called acquiring the lock of the object) where the above method is.
synchronized(this) means that the current thread will lock the entire object. No other thread can therefore access this object until the current thread leave the synchronized block and release the object. Even though the example you have given is not a necessary situation of synchronization, the thing that happens behind is the same.
Its a keyword and it will allow only single thread at a time to enter into the block.
It will achieve this by acquiring lock on this object.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
synchronized block vs synchronized method?
From accepted answer to this question: In Java critical sections, what should I synchronize on?
I learn that
public synchronized void foo() {
// do something thread-safe
}
and:
public void foo() {
synchronized (this) {
// do something thread-safe
}
}
do exactly the same thing. But in first case we make synchronized only one method of object, and in second case we make inaccessible Whole object. So why this two code snippests do same things?
You seem to be mixing things.
Firstly
public synchronized void method() {
}
is equivalent, from a synchronization perspective, to:
public void method() {
synchronized (this) {
}
}
The pros / cons have already been mentioned and the various duplicates give more information.
Secondly,
synchronized(someObject) {
//some instructions
}
means that the instructions in the synchronized block can't be executed simultaneously by 2 threads because they need to acquire the monitor on someObject to do so. (That assumes that someObject is a final reference that does not change).
In your case, someObject happens to be this.
Any code in your object that is not synchronized, can still be executed concurrently, even if the monitor on this is held by a thread because it is running the synchronized block. In other words, synchronized(this) does NOT "lock the whole object". It only prevents 2 threads from executing the synchronized block at the same time.
Finally, if you have two synchronized methods (both using this as a lock), if one thread (T1) acquires a lock on this to execute one of those 2 methods, no other thread is allowed to execute any of the two methods, because they would need to acquire the lock on this, which is already held by T1.
That situation can create contention in critical sections, in which case a more fine grained locking strategy must be used (for example, using multiple locks).
We don't synchronize an object, instead we synchronize a block of code. In the first that block of code is the method itself, while in the second it's the synchronized block.
The object only provides the lock so as to prevent multiple threads from simultaneously entering that block of code. In the first case, the this object (the one on which the method is invoked) will be used implicitly as the lock, while in the second case it doesn't always have to be this object, it could be some other object also.
They do the same thing. The first form is a short-hand for the second form.
One minor difference between the two constructs is this - synchronized blocks are compiled into monitorenter (op-code 0xC2) and monitorexit (op-code 0xC3) instructions.
A synchronized method, when compiled, is distinguished in the runtime constant pool by
the ACC_SYNCHRONIZED flag, which is checked by JVM’s the method invocation instructions. This difference does not have much significance in practice though.
They dont do same things. First part being synched from beginning to end. Second is just synching the block(not whole method). Second one has some flexibility.
I was wondering if you have a static method that is not synchronised, but does not modify any static variables is it thread-safe? What about if the method creates local variables inside it? For example, is the following code thread-safe?
public static String[] makeStringArray( String a, String b ){
return new String[]{ a, b };
}
So if I have two threads calling ths method continously and concurrently, one with dogs (say "great dane" and "bull dog") and the other with cats (say "persian" and "siamese") will I ever get cats and dogs in the same array? Or will the cats and dogs never be inside the same invocation of the method at the same time?
This method is 100% thread safe, it would be even if it wasn't static. The problem with thread-safety arises when you need to share data between threads - you must take care of atomicity, visibility, etc.
This method only operates on parameters, which reside on stack and references to immutable objects on heap. Stack is inherently local to the thread, so no sharing of data occurs, ever.
Immutable objects (String in this case) are also thread-safe because once created they can't be changed and all threads see the same value. On the other hand if the method was accepting (mutable) Date you could have had a problem. Two threads can simultaneously modify that same object instance, causing race conditions and visibility problems.
A method can only be thread-unsafe when it changes some shared state. Whether it's static or not is irrelevant.
The function is perfectly thread safe.
If you think about it... assume what would happen if this were different. Every usual function would have threading problems if not synchronized, so all API functions in the JDK would have to be synchronized, because they could potentially be called by multiple threads. And since most time the app is using some API, multithreaded apps would effectively be impossible.
This is too ridiculous to think about it, so just for you: Methods are not threadsafe if there is a clear reason why there could be problems. Try to always think about what if there were multiple threads in my function, and what if you had a step-debugger and would one step after another advance the first... then the second thread... maybe the second again... would there be problems? If you find one, its not thread safe.
Please be also aware, that most of the Java 1.5 Collection classes are not threadsafe, except those where stated, like ConcurrentHashMap.
And if you really want to dive into this, have a close look at the volatile keyword and ALL its side effects. Have a look at the Semaphore() and Lock() class, and their friends in java.util.Concurrent. Read all the API docs around the classes. It is worth to learn and satisfying, too.
Sorry for this overly elaborate answer.
Use the static keyword with synchronized static methods to modify static data shared among threads. With the static keyword all the threads created will contend for a single version of the method.
Use the volatile keyword along with synchronized instance methods will guarantee that each thread has its own copy of the shared data and no read/ writes will leak out between threads.
String objects being immutable is another reason for thread-safe scenario above. Instead if mutable objects are used (say makeMutableArray..) then surely thread-safety will break.
Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread. So all the methods are thread safe until they change the state of some static variable.
See also:
Is static method is thread safe in Java?
I am new to multithreading, and I wrote this code which prints the numbers 1-10000 by having concurrently running threads increment and print a variable.
Here's the code I'm using:
package threadtest;
public class Main{
static int i=0;
static Object lock=new Object();
private static class Incrementer extends Thread{
#Override
public void run(){
while (true){
synchronized(lock){
if (i>=10000)
break;
i++;
System.out.println(i);
}
}
}
}
public static void main(String[] args) {
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
}
}
This works - I wrote up a test program to check the output, and the numbers printed are exactly 1-10000 in order.
My question is this: I've heard that synchronized is only syntactic sugar. But I can't seem to achieve a successful result without using it. What am I missing?
synchronized is by no means syntactic sugar for anything. There is no way to work locks in Java without using the synchronized keyword.
Where there is "syntactic sugar" of a sort in locks in Java is that synchronized can apply both to blocks (as you've done it above) and to whole methods. The following two methods are roughly equivalent in semantics:
synchronized void method1() {
// ... do stuff ...
}
void method2() {
synchronized(this) {
// ... do stuff ...
}
}
So why would you want to do the second version instead of the first?
Synchronized method invocations are far slower than plain old method invocations, like by about an order of magnitude. If your synchronized code isn't guaranteed to always execute (say it's in a conditional), then you probably don't want to synchronize the whole method.
Synchronized methods hold locks for longer than synchronized blocks (because of all the method setup/tear down code). The second method above will hold the lock for less time because the time spent setting up and tearing down the stack frame won't be locked.
You can have much finer control over exactly what you're locking if you go with the synchronized blocks.
(Courtesy of starblue) Synchronized blocks can use objects other than this for locking which gives you more flexible locking semantics.
It sounds like your sources are just wrong. The syncrhonized keyword is important to use - and use properly - when writing thread-safe code. And it sounds like your own experiments bear this out.
For more on synchronization in Java:
Java Synchronized Methods
Java Locks and Synchronized Statements
Actually as of Java 5 you (formally) have an alternative set of tools in java.util.concurrent. See here for more details. As detailed in the article the monitor locking model provided at Java's language level has a number of significant limitations and can be difficult to reason about when there are a complex set of interdependent objects and locking relationships making live-lock a real possibility. The java.util.concurrent library offers locking semantics which might be more familiar to programmers who've had experience in POSIX-like systems
Of course, "synchronized" is just syntactic sugar - extremley useful syntactic sugar.
If you want sugar-free java programs, you should be writing directly in java byte code the monitorenter, monitorexit, lock, and unlock operations referenced in VM Specifications 8.13 Locks and Synchronization
There is a lock associated with every object. The Java programming
language does not provide a way to
perform separate lock and unlock
operations; instead, they are
implicitly performed by high-level
constructs that always arrange to pair
such operations correctly. (The Java
virtual machine, however, provides
separate monitorenter and monitorexit
instructions that implement the lock
and unlock operations.)
The synchronized statement computes a
reference to an object; it then
attempts to perform a lock operation
on that object and does not proceed
further until the lock operation has
successfully completed. (A lock
operation may be delayed because the
rules about locks can prevent the main
memory from participating until some
other thread is ready to perform one
or more unlock operations.) After the
lock operation has been performed, the
body of the synchronized statement is
executed. Normally, a compiler for the
Java programming language ensures that
the lock operation implemented by a
monitorenter instruction executed
prior to the execution of the body of
the synchronized statement is matched
by an unlock operation implemented by
a monitorexit instruction whenever the
synchronized statement completes,
whether completion is normal or
abrupt.
A synchronized method automatically
performs a lock operation when it is
invoked; its body is not executed
until the lock operation has
successfully completed. If the method
is an instance method, it locks the
lock associated with the instance for
which it was invoked (that is, the
object that will be known as this
during execution of the method's
body). If the method is static, it
locks the lock associated with the
Class object that represents the class
in which the method is defined. If
execution of the method's body is ever
completed, either normally or
abruptly, an unlock operation is
automatically performed on that same
lock.
Best practice is that if a variable is
ever to be assigned by one thread and
used or assigned by another, then all
accesses to that variable should be
enclosed in synchronized methods or
synchronized statements.
Although a compiler for the Java
programming language normally
guarantees structured use of locks
(see Section 7.14, "Synchronization"),
there is no assurance that all code
submitted to the Java virtual machine
will obey this property.
Implementations of the Java virtual
machine are permitted but not required
to enforce both of the following two
rules guaranteeing structured locking.
Let T be a thread and L be a lock.
Then:
The number of lock operations performed by T on L during a method
invocation must equal the number of
unlock operations performed by T on L
during the method invocation whether
the method invocation completes
normally or abruptly.
At no point during a method invocation may the number of unlock
operations performed by T on L since
the method invocation exceed the
number of lock operations performed by
T on L since the method invocation.
In less formal terms, during a method
invocation every unlock operation on L
must match some preceding lock
operation on L.
Note that the locking and unlocking
automatically performed by the Java
virtual machine when invoking a
synchronized method are considered to
occur during the calling method's
invocation.
Synchronization is one of the most important concepts while programming in multi thread environment.
While using synchronization one has to consider the object over which synchronization takes place.
For example if a static method is to be synchronized then the synchronization must be on the class level using
synchronized(MyClass.class){
//code to be executed in the static context
}
if the block in instance method is to be synchronized then the synchronization must be using an instance of an object which is shared between all the threads.
Most poeple go wrong with the second point as it appears in your code where the synchronization appears to be on different objects rather than a single object.