I am going through this link , here the implementation of coiunting semaphore is given as :
public class CountingSemaphore {
private int signals = 0;
public synchronized void take() {
this.signals++;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.signals--;
}
}
i am not able to get that. in the take() method , notify is called which will make other threads to enter the section.Shouldnt there be wait inside take method. please help me understand.
Thanks
Jayendra
The first comment on that article points out:
Don't you have "take" and "release" reversed?
and the author concedes
You are right, that should probably have been reversed.
So, yes, it seems the article got things mixed up a bit.
It probably works if you just switch these two methods.
However, in real life, the JDK has semaphores now in the concurrency utils package, and you should use those.
As for learning how things work, looking at the JDK source as a first step is probably a bit challenging (but very good reading after you have reached an initial understanding). Best to find a better article.
Use java.util.concurrent.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.
Grep the code.
The method names are switched by a translation error, see the original author's comment. The code makes no sense in this form, since it will produce a deadlock: the release will only decrease the counter if it's zero, which will never happen again!
If you swap the calls, i.e. lock by calling 'release', the semaphore will work, but not count.
Related
I have a method similar to the one below:
public void addSubjectsToCategory() {
final List<Subject> subjectsList = new ArrayList<>(getSubjectList());
for (final Iterator<Subject> subjectIterator =
subjectsList.iterator(); subjectIterator.hasNext();) {
addToCategory(subjectIterator.next().getId());
}
}
When this runs concurrently for the same user (another instance), sometimes it throws NoSuchElementException. As per my understanding, sometimes subjectIterator.next() get executed when there are no elements in the list. This occurs when being accessed only. Will method synchronization solve this issue?
The stack trace is:
java.util.NoSuchElementException: null
at java.util.ArrayList$Itr.next(Unknown Source)
at org.cmos.student.subject.category.CategoryManager.addSubjectsToCategory(CategoryManager.java:221)
This stack trace fails at the addToCategory(subjectIterator.next().getId()); line.
The basic rule of iterators is that underlying collection must not be modified while the iterator is being used.
If you have a single thread, there seems to be nothing wrong with this code as long as getSubjectsList() does not return null OR addToCategory() or getId() have some strange side-effects that would modify the subjectsList. Note, however, that you could rewrite the for-loop somewhat nicer (for(Subject subject: subjectsList) ...).
Judging by your code, my best guess is that you have another thread which is modifying subjectsList somewhere else. If this is the case, using a SynchronizedList will probably not solve your problem. As far as I know, synchronization only applies to List methods such as add(), remove() etc., and does not lock a collection during iteration.
In this case, adding synchronized to the method will not help either, because the other thread is doing its nasty stuff elsewhere. If these assumptions are true, your easiest and safest way is to make a separate synchronization object (i.e. Object lock = new Object()) and then put synchronized (lock) { ... } around this for loop as well as any other place in your program that modifies the collection. This will prevent the other thread from doing any modifications while this thread is iterating, and vice versa.
subjectIterator.hasNext();) {
--- Imagine a thread switch occurs here, at this point, between the call to hasNext() and next() methods.
addToCategory(subjectIterator.next().getId());
What could happen is the following, assuming you are at the last element in the list:
thread A calls hasNext(), the result is true;
thread switch occurs to thread B;
thread B calls hasNext(), the result is also true;
thread B calls next() and gets the next element from the list; now the list is empty because it was the last one;
thread switch occurs back to thread A;
thread A is already inside the body of the for loop, because this is where it was interrupted, it already called hasNext earlier, which
was true;
so thread A calls next(), which fails now with an exception, because there are no more elements in the list.
So what you have to do in such situations, is to make the operations hasNext and next behave in an atomic way, without thread switches occurring in between.
A simple synchronization on the list solves, indeed, the problem:
public void addSubjectsToCategory() {
final ArrayBlockingQueue<Subject> subjectsList = new ArrayBlockingQueue(getSubjectList());
synchronized (subjectsList) {
for (final Iterator<Subject> subjectIterator =
subjectsList.iterator(); subjectIterator.hasNext();) {
addToCategory(subjectIterator.next().getId());
}
}
}
Note, however, that there may be performance implications with this approach. No other thread will be able to read or write from/to the same list until the iteration is over (but this is what you want). To solve this, you may want to move the synchronization inside the loop, just around hasNext and next. Or you may want to use more sophisticated synchronization mechanisms, such as read-write locks.
It sounds like another thread is calling the method and grabbing the last element while another thread is about to get the next. So when the other thread finishes and comes back to the paused thread there is nothing left. I suggest using an ArrayBlockingQueue instead of a list. This will block threads when one is already iterating.
public void addSubjectsToCategory() {
final ArrayBlockingQueue<Subject> subjectsList = new ArrayBlockingQueue(getSubjectList());
for (final Iterator<Subject> subjectIterator =
subjectsList.iterator(); subjectIterator.hasNext();) {
addToCategory(subjectIterator.next().getId());
}
}
There is a bit of a wrinkle that you may have to sort out. The ArrayBlockingQueue will block if it is empty or full and wait for a thread to either insert something or take something out, respectively, before it will unblock and allow other threads to access.
You can use Collections.synchronizedList(list) if all you need is a simple invocation Sycnchronization. But do note that the iterator that you use must be inside the Synchronized block.
As I get you are adding elements to a list which might be under reading process.
Imagine the list is empty and your other thread is reading it. These kinds of problems might lead into your problem. You could never be sure that an element is written to your list which you are trying to read , in this approach.
I was surprised not to see an answer involving the use of a CopyOnWriteArrayList or Guava's ImmutableList so I thought that I would add such an answer here.
Firstly, if your use case is such that you only have a few additions relative to many reads, consider using the CopyOnWriteArrayList to solve the concurrent list traversal problem. Method synchronization could solve your issue, but CopyOnWriteArrayList will likely have better performance if the number of concurrent accesses "vastly" exceeds the number of writes, as per that class's Javadoc.
Secondly, if your use case is such that you can add everything to your list upfront in a single-threaded manner and only then do you need iterate across it concurrently, then consider Guava's ImmutableList class. You accomplish this by first using a standard ArrayList or a LinkedList or a builder for your ImmutableList. Once your single-threaded data entry is complete, then you instantiate your ImmutableList using either ImmutableList.copyOf() or ImmutableList.build(). If your use case will allow for this write/read pattern, this will probably be your most performant option.
Hope that helps.
I would like to make a suggestion that would probably solve your problem, considering that this is a concurrency issue.
If making the method addSubjectsToCategory() synchronized solves your problem, then you have located where your concurrency issue is. It is important to locate where the problem occurs, otherwise the information you provided is useless to us, we can't help you.
IF using synchronized in your method solves your problem, then consider this answer as educational or as a more elegant solution. Otherwise, share the code where you implement your threading environment, so we can have a look.
public synchronized void addSubjectsToCategory(List subjectsList){
Iterator iterator = subjectsList.iterator();
while(iterator.hasNext())
addToCategory(iterator.next().getId());
}
or
//This semaphore should be used by all threads. Be careful not to create a
//different semaphore each time.
public static Semaphore mutex = new Semaphore(1);
public void addSubjectsToCategory(List subjectsList){
Iterator<Subject> iterator = subjectsList.iterator();
mutex.acquire();
while(iterator.hasNext())
addToCategory(iterator.next().getId());
mutex.release();
}
Synchronized is clean, tidy and elegant. You have a really small method and creating locks, imho is unnecessary.
Synchronized means that only 1 thread will be able to enter the method at a time. Which means, you should use it only if you want 1 thread active each time.
If you actually need parallel execution, then your problem is not thread-related, but has something to do with the rest of your code, which we can not see.
Is this Java class thread safe or reset method needs to be synchronized too? If yes can someone tell me the reason why?
public class NamedCounter {
private int count;
public synchronized void increment() { count++; }
public synchronized int getCount() { return count; }
public void reset() { count = 0; }
}
Not without synchronizing rest() and adding more methods. You will run into cases where you will need more methods. For example
NamedCounter counter = new NamedCounter();
counter.increment();
// at this exact time (before reaching the below line) another thread might change changed the value of counter!!!!
if(counter.getCount() == 1) {
//do something....this is not thread safe since you depeneded on a value that might have been changed by another thread
}
To fix the above you need something like
NamedCounter counter = new NamedCounter();
if(counter.incrementAndGet()== 1) { //incrementAndGet() must be a synchronized method
//do something....now it is thread safe
}
Instead, use Java's bulit-in class AtomicInteger which covers all cases. Or if you are trying to learn thread safety then use AtomicInteger as a standard (to learn from).
For production code, go with AtomicInteger without even thinking twice! Please note that using AtomicInteger does not automatically guarantee thread safety in your code. You MUST make use of the methods that are provided by the api. They are there for a reason.
Note that synchronized is not just about mutual exclusion, it is fundamentally about the proper ordering of operations in terms of the visibility of their actions. Therefore reset must be synchronized as well, otherwise the writes it makes may occur concurrently to other two methods, and have no guarantee to be visible.
To conclude, your class is not thread-safe as it stands, but will be as soon as you synchronize the reset method.
You have to synchronize your reset() method also.
To make a class thread safe you have to synchronize all paths that access a variable else you will have undesired results with the unsynchronized paths.
You need to add synchronized to reset method too and then it will be synchronized. But in this way you achieve syncronization through locks, that is, each thread accesing the method will lock on the NamedCounter object instace.
However, if you use AtomicInteger as your count variable, you don't need to syncronize anymore because it uses the CAS cpu operation to achieve atomicity without the need to synchronize.
Not an answer, but too long for a comment:
If reset() is synch'ed, then the 0 become visible to any thread that reads or increments the counter later. Without synchronization, there is no visibility guarantee. Looking at the interaction of concurrent increment and the unsychronized reset, it may be that 0 becomes visible to the incrementing thread before entering the method, then the result will be 1. If counter is set to 0 between increment's read and write, the reset will be forgotten. If it is set after the write, the end result will be 0. So, if you want to assert that for every reading thread, the counter is 0 after reset, that method must be synchronized, too. But David Schwartz is correct that those low-level synchronizations make little sense whithout higher-level semantics of those interactions.
I wrote this method whose purpose is to give notice of the fact that a thread is leaving a
specific block of code
A thread stands for a car which is leaving a bridge so other cars can traverse it .
The bridge is accessible to a given number of cars (limited capacity) and it's one way only.
public void getout(int diection){
// release the lock
semaphore.release();
try{
lock.lock(); //access to shared data
if(direction == Car.NORTH)
nNordTraversing--; //decreasing traversing threads
else
nSudTraversing--;
bridgeCond.signal();
}finally{
lock.unlock();
}
}
My question is: should I use lock.lock(); or it's just nonsense?
thanks in advance
As we don't have the complete code (what is that semaphore ?), this answer is partly based on guess.
If your question is related to the increment and decrement operations, then you should know that those operation aren't, in fact, atomic.
So yes, if you have other threads accessing those variables, you need to protect them to ensure that no other thread can read them or worse try to do the same operation, as two parallel increments may result in only one effective.
But as locking has a cost, you may also encapsulate your variable in AtomicLong.
From the code snippet and requirement getout will not be called by simulatenous thread, only thread which is at the front of the queue, hence the method which is calling getout should be synchronized, as not all threads(cars) can be at the front of the queue.
I also think you are using semaphore as your guard lock in the calling method.
If in your implementation getout is being called by multiple methods then yes you need synchronization and your code is correct.
Well, I assume that nNordTraversing and nSudTraversing are shared data. Since ++ and -- are not atomic operations it is sensefull to lock them, before changing. Otherwise what could happen is the following:
you read the variable nNordTraversing (e.g. 7)
another Thread gets scheduled and completes its getout method, it changed the variable (e.g. 7 -- --> 6)
you are scheduled back, change the variable but on the old data you read (e.g. 7 --> 8)before the other thread changed it
the changes of the other thread got over written, the count is not consistent anymore (e.g. its 8 now, but should be 7)
This is called the lost update problem.
I see this code quite frequently in some OSS unit tests, but is it thread safe ? Is the while loop guaranteed to see the correct value of invoc ?
If no; nerd points to whoever also knows which CPU architecture this may fail on.
private int invoc = 0;
private synchronized void increment() {
invoc++;
}
public void isItThreadSafe() throws InterruptedException {
for (int i = 0; i < TOTAL_THREADS; i++) {
new Thread(new Runnable() {
public void run() {
// do some stuff
increment();
}
}).start();
}
while (invoc != TOTAL_THREADS) {
Thread.sleep(250);
}
}
No, it's not threadsafe. invoc needs to be declared volatile, or accessed while synchronizing on the same lock, or changed to use AtomicInteger. Just using the synchronized method to increment invoc, but not synchronizing to read it, isn't good enough.
The JVM does a lot of optimizations, including CPU-specific caching and instruction reordering. It uses the volatile keyword and locking to decide when it can optimize freely and when it has to have an up-to-date value available for other threads to read. So when the reader doesn't use the lock the JVM can't know not to give it a stale value.
This quote from Java Concurrency in Practice (section 3.1.3) discusses how both writes and reads need to be synchronized:
Intrinsic locking can be used to guarantee that one thread sees the effects of another in a predictable manner, as illustrated by Figure 3.1. When thread A executes a synchronized block, and subsequently thread B enters a synchronized block guarded by the same lock, the values of variables that were visible to A prior to releasing the lock are guaranteed to be visible to B upon acquiring the lock. In other words, everything A did in or prior to a synchronized block is visible to B when it executes a synchronized block guarded by the same lock. Without synchronization, there is no such guarantee.
The next section (3.1.4) covers using volatile:
The Java language also provides an alternative, weaker form of synchronization, volatile variables, to ensure that updates to a variable are propagated predictably to other threads. When a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.
Back when we all had single-CPU machines on our desktops we'd write code and never have a problem until it ran on a multiprocessor box, usually in production. Some of the factors that give rise to the visiblity problems, things like CPU-local caches and instruction reordering, are things you would expect from any multiprocessor machine. Elimination of apparently unneeded instructions could happen for any machine, though. There's nothing forcing the JVM to ever make the reader see the up-to-date value of the variable, you're at the mercy of the JVM implementors. So it seems to me this code would not be a good bet for any CPU architecture.
Well!
private volatile int invoc = 0;
Will do the trick.
And see Are java primitive ints atomic by design or by accident? which sites some of the relevant java definitions. Apparently int is fine, but double & long might not be.
edit, add-on. The question asks, "see the correct value of invoc ?". What is "the correct value"? As in the timespace continuum, simultaneity doesn't really exist between threads. One of the above posts notes that the value will eventually get flushed, and the other thread will get it. Is the code "thread safe"? I would say "yes", because it won't "misbehave" based on the vagaries of sequencing, in this case.
Theoretically, it is possible that the read is cached. Nothing in Java memory model prevents that.
Practically, that is extremely unlikely to happen (in your particular example). The question is, whether JVM can optimize across a method call.
read #1
method();
read #2
For JVM to reason that read#2 can reuse the result of read#1 (which can be stored in a CPU register), it must know for sure that method() contains no synchronization actions. This is generally impossible - unless, method() is inlined, and JVM can see from the flatted code that there's no sync/volatile or other synchronization actions between read#1 and read#2; then it can safely eliminate read#2.
Now in your example, the method is Thread.sleep(). One way to implement it is to busy loop for certain times, depending on CPU frequency. Then JVM may inline it, and then eliminate read#2.
But of course such implementation of sleep() is unrealistic. It is usually implemented as a native method that calls OS kernel. The question is, can JVM optimize across such a native method.
Even if JVM has knowledge of internal workings of some native methods, therefore can optimize across them, it's improbable that sleep() is treated that way. sleep(1ms) takes millions of CPU cycles to return, there is really no point optimizing around it to save a few reads.
--
This discussion reveals the biggest problem of data races - it takes too much effort to reason about it. A program is not necessarily wrong, if it is not "correctly synchronized", however to prove it's not wrong is not an easy task. Life is much simpler, if a program is correctly synchronized and contains no data race.
As far as I understand the code it should be safe. The bytecode can be reordered, yes. But eventually invoc should be in sync with the main thread again. Synchronize guarantees that invoc is incremented correctly so there is a consistent representation of invoc in some register. At some time this value will be flushed and the little test succeeds.
It is certainly not nice and I would go with the answer I voted for and would fix code like this because it smells. But thinking about it I would consider it safe.
If you're not required to use "int", I would suggest AtomicInteger as an thread-safe alternative.
Has anyone got any idea how to implement a rudimentary semaphore in java without making use of wait(), notify() or synchronize.I am not looking for a solution to this problem just a pointer in the right direction because I amd totally lost on this.
java.util.concurrent.Semaphore
I had similar homework few years ago at my university, but in C++. Java is too high level language for this kind of stuff.
Here is my implementation of signal and wait in C++, but I don't know if it is going to be helpful because you will have to implement a lot of other things.
int KernelSem::wait() {
lock();
if(--value < 0) {
PCB::running->state = PCB::BLOCKED;
PCB::running->waitingAtSem = this;
blockedQueue->put(PCB::running);
dispatch();
}
else {
PCB::running->deblockedBy = 0;
if(semPreempt) dispatch();
}
unlock();
return PCB::running->deblockedBy;
}
void KernelSem::signal() {
lock();
if(value++ < 0) {
PCB* tempPCB = blockedQueue->get();
if(tempPCB) {
tempPCB->state = PCB::READY;
tempPCB->deblockedBy = 0;
tempPCB->waitingAtSem = 0;
Scheduler::put(tempPCB);
}
}
if(semPreempt) dispatch();
unlock();
}
lock and unlock functions are just asm{cli} and asm{sti} (clear/set interrupt flag).
PCB is a process control block.
Hope it helps
in a very simple simple (again) simple way you could implement this using a simple int or boolean.
Test the int or boolean before grant acess. If it is 0 (tired of boolean), add 1 and continue. If not do Thread.yield() and try again latter. When you release, remove 1 from int and continue.
naive implementation, but works fine.
I hope that this is homework, because I cannot see any good reason you might want to do this in production code. Wikipedia has a list of algorithms for implementing semaphores in software.
Doing as proposed in the accepted answer will lead to a lot of concurrent issues as you can't ensure mutual exclusion with this. As an example, two threads asking to increment an integer would both read the boolean (that is proposed as lock) the same time, then both will think it's ok and then both set the bool to its opposite value. Both threads will go in changing stuff and when they are done they will both write a value to the (non)mutually exclusive variable and the whole purpose of the semaphore is lost. The wait() method is for waiting until something happen, and that's exactly what you want to do.
If you absolutely don't want to use wait, then implement some kind of double checking sleep technique where the thread first check the lock variable, changes it to false and sets a flag in an array or something with a special slot just for that thread to ensure that it will always succeed. Then the thread can sleep for a small interval of time and then checks the whole array for more flags to see if someone else were at it the same time. If not, it can continue, else it can't continue and have to sleep for a random amount of time before trying again (to make the threads sleep for lengths to make someone success later). If they collapse again then they will sleep for an even longer random time. This technique is also used in networks where semaphores cannot be used.
(Of course semaphores is exactly what you want to do but as it uses wait i kind of assumed you wanted something that don't use wait at all...)