I'm starting with Threads, Semaphores, volatile variables, etc.
I wonder if when I'm using Semaphores it is necessary to define the variable as volatile, I mean:
Having 2 Threads, one increases and the other decreases the variable for example and obviously, before each access I have a mutex that controls at any time only one thread is "playing" with the variable.
It would be necessary to define as volatile?
From API doc of Semaphore:
Memory consistency effects: Actions in a thread prior to calling a
"release" method such as release() happen-before actions following a
successful "acquire" method such as acquire() in another thread.
So it is safe to read/write variables that are guarded by a semaphore. No need to declare them as volatile.
Semaphores should not be used in the place of synchronized because semaphores does not hold exclusive mutual lock even if it is initialized to one, like synchronized on some object. It is true that the semaphore initialized to one, allows only one thread at a time to access the object, which holds the permit. But the thread which holds the permit does not own it, any other thread could release that permit and acquire the permit. So, two threads could get access to the same object at the same time, and if both threads manipulates that object, there will be multi-threading issues like lost update, stale read etc.
In your example of having 2 threads, one increasing and one decreasing the same variable. mutual exclusion is sufficient and volatile declaration is not needed. here I assume mutual exclusion is achieved via synchronized and not by semaphores.
volatile is less strict than synchronized, you may want to use volatile when the operations performed are atomic (read or write). volatile should not be used when the performing read-update-write operation.
I wonder if when I'm using Semaphores it is necessary to define the
variable as volatile,
I dont think there is any such restriction. A mutex is a mutual exclusion semaphore, a special variant of a semaphore that only allows one locker at a time. It's equivalent to a normal counting semaphore with a count of one and the requirement that it can only be released by the same thread that locked it.
If we talk specifically for Semaphore in Java: A semaphore is a counter of permits and acquire is like decrement which waits rather than go below zero. It has no upper limit. As mentioned in CIP:
The implementation has no actual permit objects, and Semaphore does
not associate dispensed permits with threads, so a permit acquired in
one thread can be released from another thread. You can think of
acquire as consuming a permit and release as creating one; a
Semaphore is not limited to the number of permits it was created with.
For your scenario you can share a counter and make it volatile or better use AtomicInteger as they use CAS mechanism which performs really well under low contention.
Related
If you used bit masks to store read and write lock in a single AtomicInteger, could you realize a fast ReadWriteLock class?
How would it be different from a regular ReentrantReadWriteLock?
TL;DR - It won't work.
As #Radiodef points out, you would not be able to implement the ReadWriteLock API. Methods such as getOwner, getQueuedThreads and so on are unimplementable if the state of the lock is just a single AtomicInteger.
Full reentrancy would be unimplementable. Reentrancy typically requires you to encode the identities of the threads currently holding the lock, and the reentry count for each one. For the readers we could use a single count (and no identity) but the single writer needs both an identity and a count. Shoe-horning a count and a thread identity into 32 bit integer probably won't work. (A Thread does offer a numeric id attribute that is unique and unchanging for the thread's lifetime ... but the id is a long.)
If you use just a single AtomicInteger as the state of the lock, you cannot park a thread waiting on a contended lock. (For parking to work, the thread that releases a lock needs to know which thread to unpark. But you can't represent that.) This means that you would need to use spinlocking1 which is expensive and not scaleable.
In summary, you can't implement the ReadWriteLock API, or full reentrancy semantics. If you removed those requirements, you could possibly implement simple read-write locks (reentrant for readers, nonreentrant for writers) but you would need to do spinlocking.
1 - With spinlocking, a thread waiting for a contended lock "spins" executing a busy loop until the lock is available. This is OK for locks when contention is unlikely and short-lived ... or when there is nothing else that the core could do. But it is too inefficient for normal uses.
Some people says if multiple threads are reading/writing then you need to use synchronized and if one thread is reading/writing and another one is only reading then you must use volatile. I don't get the difference between this situations.
Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it.
Then If I define a variable as volatile, first threadA will read its value, threadA will update its value and write it to memory.After that variable will become visible to threadB. Then why do I need to synchronized block?
Some people says if multiple threads are reading/writing then you need to use synchronized and if one thread is reading/writing and another one is only reading then you must use volatile. I don't get the difference between this situations.
There really isn't a hard and fast rule with this. Choosing whether or not to use synchronized or volatile has more to do with how the objects are being updated as opposed to how many readers or writers there are.
For example, you can achieve multiple readers and writers with an AtomicLong which wraps a volatile long.
private AtomicLong counter = new AtomicLong();
...
// many threads can get/set this counter without synchronized
counter.incrementAndGet();
And there are circumstances where you would need a synchronized block even with a single reader/writer.
synchronized (status) {
status.setNumTransactions(dao.getNumTransactions());
// we don't want the reader thread to see `status` partially updated here
status.setTotalMoney(dao.getTotalMoney());
}
In the above example, since we are making multiple calls to update the status object we may need to ensure that other threads don't see it when the num-transactions has been updated but not the total-money. Yes, AtomicReference handles some of these cases but not all.
To be clear, marking a field volatile ensures memory synchronization. When you read a volatile field you cross a read memory barrier and when you write it you cross a write memory barrier. A synchronized block has a read memory barrier at the start and a write barrier at the end of the block and is has mutex locking to ensure only one thread can enter the block at once.
Sometimes you just need memory barriers to achieve proper sharing of data between threads and sometimes you need locking.
As comments suggest, you might do some further reading. But to give you an idea you can take a look at this stackoverflow question and think for example about the following scenario:
You have couple of variables which need to be in the right state. But although you make them all volatile you need time to update them by some code executing.
Exactly this code may be executed almost at the same time by a different thread. The first variables could be "OK" and somehow synchronized but some other maybe dependent on the first ones and are not correct yet. Thus you need a synchronized block in that case.
To add one more post for further reading about volatile look here
The primary difference between volatile and synchronized is that volatile only guarantees visibility whereas synchronized guarantees both visibility and locking.
If there are multiple read threads and one write thread then volatile usage can ensure that changes by the write thread to the volatile variable are visible to other threads immediately. But you see in this case locking isn't a problem because you only have 1 writing thread.
There are certain rules of thumb for a volatile:
Don't use volatile when its value depends on its previous value
Don't use volatile when it participates in interactions with other invariants
Don't use volatile when there are multiple write threads that update value of volatile variable.
In general, use of volatile should be limited to only those cases where it's relatively easy to reason about its state such as in the case of status flags.
In all other cases where you have shared mutable state always use synchronized wherever shared mutable state is being touched unless declared final and modified only in the constructor without unsafe publication. Volatile is a replacement for synchronized only in special cases as described in my 3 points.
Do I only need to mark a field volatile if multiple threads are reading it at the same time?
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
In my scenario, is there a happens-before relationship enforced (without the volatile keyword)?
You need the volatile keyword or some other synchronization mechanism to enforce the "happens before" relationship that guarantees visibility of the variable in threads other than the thread in which it was written. Without such synchronization, everything is treated as happening "at the same time", even if it doesn't by wall clock time.
In your particular example, one thing that may happen without synchronization is that the value written by thread A is never flushed from cache to main memory, and thread B executes on another processor and never sees the value written by thread A.
When you are dealing with threads, wall clock time means nothing. You must synchronize properly if you want data to pass between threads properly. There's no shortcut to proper synchronization that won't cause you headaches later on.
In the case of your original question, some ways proper synchronization can be achieved are by using the volatile keyword, by using synchronized blocks, or by having the thread that is reading the value of the variable join() the thread in which the variable is written.
Edit: In response to your comment, a Future has internal synchronization such that calling get() on a Future establishes a "happens before" relationship when the call returns, so that also achieves proper synchronization.
No, you don't need volatile...
is there a happens-before relationship enforced (without the volatile keyword)?
...but your code needs to do something to establish "happens-before."
There will be a happens-before relationship if (and only if) your code does something that the "Java Language Specification" (JLS) says will establish "happens-before."
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
Depends on what you mean by "guaranteed." If "guaranteed" means, "established happens-before," then your code will work as expected.
One way you can guarantee it is for thread B to call threadA.join(). The JLS guarantees that if thread B calls threadA.join(), then everything thread A did must "happen before" the join() call returns.
You do not need any of the shared variables to be volatile if thread B only accesses them after joining thread A.
You can chose one of available options to achieve the same purpose.
You can use volatile to force all threads to get latest value of the variable from main memory.
You can use synchronization to guard critical data
You can use Lock API
You can use Atomic variables
Refer to this documentation page on high level concurrency constructs.
Have a look at related SE questions:
Avoid synchronized(this) in Java?
What is the difference between atomic / volatile / synchronized?
This question already has an answer here:
What's the difference in using ReentrentLock and Synchronized(object)? [duplicate]
(1 answer)
Closed 5 years ago.
I have used the synchronized keyword and re-entrant locks in Java, but I don't understand how they differ, or which is appropriate for a given situation.
How do I decide when should I use synchronized and when I should use re-entrant locks?
A ReentrantLock is:
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities.
Extended capabilities include:
The ability to have more than one condition variable per monitor. Monitors that use the synchronized keyword can only have one. This means reentrant locks support more than one wait()/notify() queue.
The ability to make the lock fair. Synchronized blocks are unfair.
"[fair] locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order."
The ability to check if the lock is being held.
The ability to get the list of threads waiting on the lock.
The disadvantages of reentrant locks are:
Need to add import statement.
Need to wrap lock acquisitions in a try/finally block. This makes it more ugly than the synchronized keyword.
The synchronized keyword can be put in method definitions which avoids the need for a block which reduces nesting.
Summary
The synchronized keyword is syntactically nicer, but the Reentrant lock has more features.
This site clearly mentioned difference between ReentrantLock and synchronized keyword in Java. I just copy and paste from there.
http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html
1) Another significant difference between ReentrantLock and synchronized keyword is fairness. synchronized keyword doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make ReentrantLock fair by specifying fairness property, while creating instance of ReentrantLock. Fairness property provides lock to longest waiting thread, in case of contention.
2) Second difference between synchronized and Reentrant lock is tryLock() method. ReentrantLock provides convenient tryLock() method, which acquires lock only if its available or not held by any other thread. This reduce blocking of thread waiting for lock in Java application.
3) One more worth noting difference between ReentrantLock and synchronized keyword in Java is, ability to interrupt Thread while waiting for Lock. In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock. Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.
4) ReentrantLock also provides convenient method to get List of all threads waiting for lock.
I have always thought of synchronization as "the hack of least resistance". It just works and most everyone understands how it works, but it has some weaknesses that could affect your design under heavy concurrency. Not least of which is any client effectively has direct access to your object's synchronization lock meaning if they grab it and hold it other clients can't. In other words, the locking implemented by default synchronization effectively "publishes" you object's internal locking mechanism. Yuk. Its like setting yourself up for self-inflicted denial-of-service.
If you make the reentrant lock internal to your class (or just don't use the synchronized but do something like synchronize on some internal object that you new up in your constructor everywhere that you want synchronization), you remove this side-effect of publishing your internal locking mechanism, with the added complexity of you having to remember where to apply this internal synchronization as your class evolves.
What is mutex and semaphore in Java ? What is the main difference ?
Unfortunately everyone has missed the most important difference between the semaphore and the mutex; the concept of "ownership".
Semaphores have no notion of ownership, this means that any thread can release a semaphore (this can lead to many problems in itself but can help with "death detection"). Whereas a mutex does have the concept of ownership (i.e. you can only release a mutex you have acquired).
Ownership is incredibly important for safe programming of concurrent systems. I would always recommend using mutex in preference to a semaphore (but there are performance implications).
Mutexes also may support priority inheritance (which can help with the priority inversion problem) and recursion (eliminating one type of deadlock).
It should also be pointed out that there are "binary" semaphores and "counting/general" semaphores. Java's semaphore is a counting semaphore and thus allows it to be initialized with a value greater than one (whereas, as pointed out, a mutex can only a conceptual count of one). The usefulness of this has been pointed out in other posts.
So to summarize, unless you have multiple resources to manage, I would always recommend the mutex over the semaphore.
Semaphore can be counted, while mutex can only count to 1.
Suppose you have a thread running which accepts client connections. This thread can handle 10 clients simultaneously. Then each new client sets the semaphore until it reaches 10. When the Semaphore has 10 flags, then your thread won't accept new connections
Mutex are usually used for guarding stuff. Suppose your 10 clients can access multiple parts of the system. Then you can protect a part of the system with a mutex so when 1 client is connected to that sub-system, no one else should have access. You can use a Semaphore for this purpose too. A mutex is a "Mutual Exclusion Semaphore".
Mutex is basically mutual exclusion. Only one thread can acquire the resource at once. When one thread acquires the resource, no other thread is allowed to acquire the resource until the thread owning the resource releases. All threads waiting for acquiring resource would be blocked.
Semaphore is used to control the number of threads executing. There will be fixed set of resources. The resource count will gets decremented every time when a thread owns the same. When the semaphore count reaches 0 then no other threads are allowed to acquire the resource. The threads get blocked till other threads owning resource releases.
In short, the main difference is how many threads are allowed to acquire the resource at once ?
Mutex --its ONE.
Semaphore -- its DEFINED_COUNT, ( as many as semaphore count)
A mutex is used for serial access to a resource while a semaphore limits access to a resource up to a set number. You can think of a mutex as a semaphore with an access count of 1. Whatever you set your semaphore count to, that may threads can access the resource before the resource is blocked.
A semaphore is a counting synchronization mechanism, a mutex isn't.
A mutex is often known as a binary semaphore. Whilst a semaphore can be created with any non-zero count a mutex is conceptually a semeaphore with an upper count of 1.
Semaphore:
A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer. However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.
Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource
Java does not have built-in Mutex API. But it can be implemented as binary semaphore.
A semaphore initialized to one, and which is used such that it only has at most one permit available, can serve as a mutual exclusion lock. This is more commonly known as a binary semaphore, because it only has two states: one permit available, or zero permits available.
When used in this way, the binary semaphore has the property (unlike many Lock implementations), that the "lock" can be released by a thread other than the owner (as semaphores have no notion of ownership). This can be useful in some specialized contexts, such as deadlock recovery.
So key differences between Semaphore and Mutex:
Semaphore restrict number of threads to access a resource throuhg permits. Mutex allows only one thread to access resource.
No threads owns Semaphore. Threads can update number of permits by calling acquire() and release() methods. Mutexes should be unlocked only by the thread holding the lock.
When a mutex is used with condition variables, there is an implied bracketing—it is clear which part of the program is being protected. This is not necessarily the case for a semaphore, which might be called the go to of concurrent programming—it is powerful but too easy to use in an unstructured, indeterminate way.
The object of synchronization Semaphore implements a classical traffic light. A traffic light controls access to a resource shared by a counter. If the counter is greater than zero, access is granted; If it is zero, access is denied. The counter counts the permissions that allow access to the shared resource. Then, to access the resource, a thread must receive permission from the traffic light. In general, to use a traffic light, the thread that wants to access the shared resource tries to acquire a permit. If the traffic light count is greater than zero, the thread acquires a permit, and the traffic light count is decremented. Otherwise the thread is locked until it can get a permission. When the thread no longer needs to access the shared resource, it releases the permission, so the traffic light count is increased. If there is another thread waiting for a permit, it acquires a permit at that time. The Semaphore class of Java implements this mechanism.
Semaphore has two builders:
Semaphore(int num)
Semaphore(int num, boolean come)
num specifies the initial count of the permit. Then num specifies the number of threads that can access a shared resource at a given time. If num is one, it can access the resource one thread at a time. By setting come as true, you can guarantee that the threads you are waiting for are granted permission in the order they requested.
You compare the incomparable, technically there is no difference between a Semaphore and mutex it doesn't make sense.
Mutex is just a significant name like any name in your application logic, it means that you initialize a semaphore at "1", it's used generally to protect a resource or a protected variable to ensure the mutual exclusion.
Mutex is binary semaphore. It must be initialized with 1, so that the First Come First Serve principle is met. This brings us to the other special property of each mutex: the one who did down, must be the one who does up. Ergo we have obtained mutual exclusion over some resource.
Now you could see that a mutex is a special case of general semaphore.