I want the server to execute a certain part of the service impl code for one client at a time, thread-safe; and sequentially. Here's the part of the server-side service implementation that does this:
public BorcData getBorcData(String userId) throws GeneralException, EyeksGwtException
{
StoredProcedure sp = DALDB.storedProcedure("BORCBILDIRIM_GETMUKDATA_SP");
DALResult spResult;
Row spRow;
String vergiNo;
String asamaOid;
synchronized (ServerUtility.lock_GeriArama_GetBorcData_GetMukDataSP)
{
String curOptime =CSDateUtility.getCurrentDateTimeToSave();
sp.addParam(curOptime);
spResult = sp.execute();
if (!spResult.hasNext())
{
throw new GeneralException("53", "");
}
}
You see the synchronized block. The object that I use for the lock is defined as:
public static Object lock_GeriArama_GetBorcData_GetMukDataSP = new Object();
My problem is: I think I saw that while a client was waiting to execute that synchronized block for a long time, some other client called this service and executed that block without getting in line and went on. The first client was still waiting.
I know that the server-side runs pure Java. Is it possible that the server-side is being unfair to the clients and not running the longest waiting client's request first?
EDIT: Actually; the fairness isn't even the real problem. Sometimes clients look like they just hang in that synchronized part; waiting forever for the service to finish.
First your lock Object always should be declared final. This isn't fixing any problems, but it tells you if you did code something wrong (like setting the lock to a different lock somewhere).
One way to ensure fairness is to use a ReentrantLock initialized with true (fair scheduling). It will ensure that clients do not hang indefinitely, but are executed in a FIFO order. The good thing is that this requires only a minor change to your code, by replacing all those synchronized blocks with:
lock.lock();
try {
// previous code
} finally {
lock.unlock();
}
The finally is just a safety measure, should any part inside throw an exception.
Other than that your code looks perfectly fine, so the issue is most likely in the DB and not caused by using synchronized at all.
Multi threading in java doesn't guarantee sequential execution.
Read the article : http://www.javaworld.com/javaworld/jw-07-2002/jw-0703-java101.html
It is much helpful in understanding how threads are scheduled.
Related
I've got a system with many writers and a single reader, each running in a separate thread. The writers notify the reader when work is available, and the reader blocks until it is notified.
Given the number of writers, I want to use a lock-free implementation to notify the reader. Every time the reader wakes up, it resets the notification flag, does some work, and blocks waiting for more notifications to arrive.
Essentially I'm looking for the equivalent of an AtomicBoolean with an ability to block until its value becomes true.
What I've tried so far:
My current implementation uses a Semaphore.
The semaphore starts out with no permits.
The reader blocks trying to acquire a permit.
Writers invoke Semaphore.release() in order to notify the reader.
The reader invokes Semaphore.drainPermits(), does some work, and blocks again on Semaphore.acquire.
What I don't like about the Semaphore approach:
It seems a bit heavy-handed. I only care about about the first notification arriving. I don't need to keep a count of how many other notifications came in.
Semaphores throw an exception if their count surpasses Integer.MAX_VALUE. This is more of a theoretical problem than practical but still not ideal.
Is there a data structure that is equivalent to AtomicBoolean with an ability to block waiting on a particular value?
Alternatively, is there a thread-safe manner to ensure that Semaphore's number of permits never surpass a certain value?
BlockingQueue<Singleton> would do this adequately.
You would create, for example, an ArrayBlockingQueue<Singleton>(1), and then your waiter would look like:
queue.take();
… and the notifier would look like:
queue.offer(Singleton.INSTANCE)
… with the use of offer ensuring that multiple releases are combined together.
FYI: The Java language includes a general mechanism for threads to await arbitrary events caused by other threads. It's rather primitive, and in many applications, you'd be better off using some higher-level, problem-specific tool such as BlockingQueue, CompletableFuture, CountdownLatch, etc. But, for those problems where the higher-level classes all "feel a bit heavy-handed," the Object class has object.wait(), object.notify(), and object.notifyAll().*
The idea is,
You have some test() that yields a boolean result,
There is a mutex that threads are required to own when performing the test or changing its result, and
There is at least one thread that needs to wait until the test yields true before it can proceed.
final Object mutex = new Object();
public boolean test() { ... }
public boolean procedureThatAffectsTheTestResult() { ... }
public boolean procedureThatRequiresTestResultToBeTrue() { ... }
A thread that needs to wait until the test result is true can do this:
synchronized (mutex) {
while (! test()) {
try {
mutex.wait();
}
catch (InterruptedException ex) {
...use your shameful imagination here...
}
}
procedureThatRequiresTestResultToBeTrue();
}
Any thread that can change the test result should do it like so:
synchronized (mutex) {
procedureThatAffectsTheTestResult();
mutex.notifyAll(); //or, mutex.notify() *IF* you know what you are doing.
}
The mutex.notifyAll() call will wake up every thread that happens to be sleeping in a mutex.wait() call at that same moment. mutex.notify() is trickier, but it will improve the performance of some applications because it will arbitrarily choose just one thread if more than one is waiting.
You may be wondering how a thread could ever enter a synchronized (mutex) block to change the test() result when another thread already is wait()ing inside another synchronized (mutex) block. The secret is that mutex.wait() temporarily unlocks the mutex while it is waiting, and then it guarantees to re-lock the mutex before returning or throwing an exception.
For a more complete description of when and why and how to use this feature, see the tutorial: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
* You can also do practically the same thing using a Condition object and a ReentrantLock, but that's a topic for another day.
In our application, there's a section of code that runs continuously reading and adjusting files. Just to give you a sense of what's going on:
public void run() {
try {
while(true) { //Yeah, I know...
Path currentFileName = getNextFile();
String string = readFile(currentFileName);
Files.deleteFile(currentFileName);
string = string.replaceAll("Hello", "Blarg");
writeFile(currentFileName);
}
} catch (Exception e) {
System.err.println("It's all ogre now.");
e.printStackTrace(System.err);
}
}
Elsewhere in our code is a method that might-but-usually-doesn't run on the same thread as the above code, that we use to exit the application.
private void shutdown() {
if(fileReader != null)
fileReader = null;
System.exit(0); //Don't blame me, I didn't write this code
}
As might be obvious, there's a potential Race Condition in this code, whereby if shutdown() is called between retrieving the file and then writing it back out, it'll potentially cause the file to be completely lost. This is, obviously, undesirable behavior.
There's a thousand issues with this code (outside the scope of just what I've shown here), but the main issue I need to resolve is the bad behavior where processing a file can be cut off halfway through with no recourse. My proposed solution involves simply wrapping the while loop in a synchronized block and putting a block around the System.exit call in shutdown.
So my changed code would look like this:
private Object monitor = new Object();
public void run() {
try {
while(true) {
synchronized(monitor) {
Path currentFileName = getNextFile();
String string = readFile(currentFileName);
Files.deleteFile(currentFileName);
string = string.replaceAll("Hello", "Blarg");
writeFile(currentFileName);
}
}
} catch (Exception e) {
System.err.println("It's all ogre now.");
e.printStackTrace(System.err);
}
}
private void shutdown() {
synchronized(monitor) {
if(fileReader != null)
fileReader = null;
System.exit(0);
}
}
The main thing I'm worried about is the System.exit(0); call, where I'm not certain about the total behavior behind the scenes of the call. Is there a risk that a side-effect of System.exit will be to release the lock on monitor, and thus risk the contents of the loop in run being executed partially before System.exit has caused the JVM to halt? Or will this code guarantee that the execution will never attempt a shutdown part-way through the handling of an individual file?
Note: before some armchair programmers step in with alternatives, I'd like to point out that what I've put here is a truncated version of about 4000 lines of code all stashed in a single class. Yes, it is awful. Yes, it makes me regret my chosen profession. I am not here looking for alternate solutions to this problem, I am only trying to determine if this specific solution will work, or if there's some critical flaw that would preclude it from ever working as I expect.
Or will this code guarantee that the execution will never attempt a shutdown part-way through the handling of an individual file?
This code guarantees that a shutdown initiated here will not occur part-way through handling of an individual file. Perhaps obviously, somewhere else in your code could invoke System.exit, and you have no protection from that.
You might want to consider preventing System.exit from being invoked, and then cause your code to shut down gracefully (i.e. by normal completion of the main method).
In case you really have multiple threads calling the different methods, using synchronized like this is actually a clever idea, as it takes care of that "multiple threads" thing.
You could consider reducing the scope of the first block:
Path currentFileName = getNextFile();
String string = readFile(currentFileName);
synchronized(monitor) {
reading the file alone shouldn't be a problem. (of course, unless your code here has to guarantee that a Path returned by getNextFile() gets fully processed).
If the code is executing in the synchronized block and the blocks synchronize on the same object, and the methods invoked in the synchronized block in the while loop operate entirely on the same thread as their caller, then there is no risk of the file-related processes being interrupted by that invocation of System.exit.
This said, it does look like a debatable patch only slightly improving debatable code.
There may also be a more concrete risk of starvation, as the while loop as displayed just seems to spam those file operations as fast as possible, hence the attempt to acquire the lock when exiting may not succeed.
A general direction to explore would be to transform the infinite while loop into a ScheduledExecutorService + Runnable, executing every x amount of time with its own monitor to prevent overlapping operations on the same file(s), and gracefully terminating it when the shutdown method is invoked.
You could use a shutdown hook. From the javadocs:
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently.
https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
From this, you could provide a shutdown hook from your file class as follows:
public Thread getShutdownHook() {
return new Thread(() -> {
synchronized (monitor) {
// gracefully handle the file object
}
});
}
This will be called when Runtime.getRuntime().exit() is called (which is called by System.exit()). Since it is also synchronized on the monitor object, if the file is in use by the other thread, the shutdown hook will block until it is free.
Even if you cope with concurrent System.exit(), other reasons remain which can lead to sudden break of execution, like power outage or hardware error.
So you better do not remove the file before the new version is written. Do something like:
Path currentFileName = getNextFile();
Path tmpFileName = currentFileName+suffix();
String string = readFile(currentFileName);
string = string.replaceAll("Hello", "Blarg");
writeFile(tmpFileName);
Files.move(tmpFileName, currentFileName);
I'm loosely following a tutorial on Java NIO to create my first multi-threading, networking Java application. The tutorial is basically about creating an echo-server and a client, but at the moment I'm just trying to get as far as a server receiving messages from the clients and logging them to the console. By searching the tutorial page for "EchoServer" you can see the class that I base most of the relevant code on.
My problem is (at least I think it is) that I can't find a way to initialize the queue of messages to be processed so that it can be used as I want to.
The application is running on two threads: a server thread, which listens for connections and socket data, and a worker thread which processes data received by the server thread. When the server thread has received a message, it calls processData(byte[] data) on the worker, where the data is added to a queue:
1. public void processData(byte[] data) {
2. synchronized(queue) {
3. queue.add(new String(data));
4. queue.notify();
5. }
6. }
In the worker thread's run() method, I have the following code:
7. while (true) {
8. String msg;
9.
10. synchronized (queue) {
11. while (queue.isEmpty()) {
12. try {
13. queue.wait();
14. } catch (InterruptedException e) { }
15. }
16. msg = queue.poll();
17. }
18.
19. System.out.println("Processed message: " + msg);
20. }
I have verified in the debugger that the worker thread gets to line 13, but doesn't proceed to line 16, when the server starts. I take that as a sign of a successful wait. I have also verified that the server thread gets to line 4, and calls notify()on the queue. However, the worker thread doesn't seem to wake up.
In the javadoc for wait(), it is stated that
The current thread must own this object's monitor.
Given my inexperience with threads I am not exactly certain what that means, but I have tried instantiating the queue from the worker thread with no success.
Why does my thread not wake up? How do I wake it up correctly?
Update:
As #Fly suggested, I added some log calls to print out System.identityHashCode(queue) and sure enough the queues were different instances.
This is the entire Worker class:
public class Worker implements Runnable {
Queue<String> queue = new LinkedList<String>();
public void processData(byte[] data) { ... }
#Override
public void run() { ... }
}
The worker is instantiated in the main method and passed to the server as follows:
public static void main(String[] args)
{
Worker w = new Worker();
// Give names to threads for debugging purposes
new Thread(w,"WorkerThread").start();
new Thread(new Server(w), "ServerThread").start();
}
The server saves the Worker instance to a private field and calls processData() on that field. Why do I not get the same queue?
Update 2:
The entire code for the server and worker threads is now available here.
I've placed the code from both files in the same paste, so if you want to compile and run the code yourself, you'll have to split them up again. Also, there's abunch of calls to Log.d(), Log.i(), Log.w() and Log.e() - those are just simple logging routines that construct a log message with some extra information (timestamp and such) and outputs to System.out and System.err.
I'm going to guess that you are getting two different queue objects, because you are creating a whole new Worker instances. You didn't post the code that starts the Worker, but assuming that it also instantiates and starts the Server, then the problem is on the line where you assign this.worker = new Worker(); instead of assigning it to the Worker parameter.
public Server(Worker worker) {
this.clients = new ArrayList<ClientHandle>();
this.worker = new Worker(); // <------THIS SHOULD BE this.worker = worker;
try {
this.start();
} catch (IOException e) {
Log.e("An error occurred when trying to start the server.", e,
this.getClass());
}
}
The thread for the Worker is probably using the worker instance passed to the Server constructor, so the Server needs to assign its own worker reference to that same Worker object.
You might want to use LinkedBlockingQueue instead, it internally handles the multithreading part, and you can focus more on logic. For example :
// a shared instance somewhere in your code
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();
in one of your thread
public void processData(byte[] data) {
queue.offer(new String(data));
}
and in your other thread
while (running) { // private class member, set to false to exit loop
String msg = queue.poll(500, TimeUnit.MILLISECONDS);
if (msg == null) {
// queue was empty
Thread.yield();
} else {
System.out.println("Processed message: " + msg);
}
}
Note : for the sake of completeness, the methode poll throws in InterruptedException that you may handle as you see fit. In this case, the while could be surrounded by the try...catch so to exit if the thread should have been interrupted.
I'm assuming that queue is an instance of some class that implements the Queue interface, and that (therefore) the poll() method doesn't block.
In this case, you simply need to instantiate a single queue object that can be shared by the two threads. The following will do the trick:
Queue<String> queue = new LinkedList<String>();
The LinkedList class is not thread-safe, but provided that you always access and update the queue instance in a synchronized(queue) block, this will take care of thread-safety.
I think that the rest of the code is correct. You appear to be doing the wait / notify correctly. The worker thread should get and print the message.
If this isn't working, then the first thing to check is whether the two threads are using the same queue object. The second thing to check is whether processData is actually being called. A third possibility is that some other code is adding or removing queue entries, and doing it the wrong way.
notify() calls are lost if there is no thread sleeping when notify() is called. So if you go notify() then another thread does wait() afterwards, then you will deadlock.
You want to use a semaphore instead. Unlike condition variables, release()/increment() calls are not lost on semaphores.
Start the semaphore's count at zero. When you add to the queue increase it. When you take from the queue decrease it. You will not get lost wake-up calls this way.
Update
To clear up some confusion regarding condition variables and semaphores.
There are two differences between condition variables and semaphores.
Condition variables, unlike semaphores, are associated with a lock. You must acquire the lock before you call wait() and notify(). Semaphore do not have this restriction. Also, wait() calls release the lock.
notify() calls are lost on condition variables, meaning, if you call notify() and no thread is sleeping with a call to wait(), then the notify() is lost. This is not the case with semaphores. The ordering of acquire() and release() calls on semaphores does not matter because the semaphore maintains a count. This is why they are sometimes called counting semaphores.
In the javadoc for wait(), it is stated that
The current thread must own this object's monitor.
Given my inexperience with threads I am not exactly certain what that
means, but I have tried instantiating the queue from the worker thread
with no success.
They use really bizarre and confusing terminology. As a general rule of thumb, "object's monitor" in Java speak means "object's lock". Every object in Java has, inside it, a lock and one condition variable (wait()/notify()). So what that line means is, before you call wait() or notify() on an object (in you're case the queue object) you much acquire the lock with synchronized(object){} fist. Being "inside" the monitor in Java speak means possessing the lock with synchronized(). The terminology has been adopted from research papers and applied to Java concepts so it is a bit confusing since these words mean something slightly different from what they originally meant.
The code seems to be correct.
Do both threads use the same queue object? You can check this by object id in a debugger.
Does changing notify() to notifyAll() help? There could be another thread that invoked wait() on the queue.
OK, after some more hours of pointlessly looking around the net I decided to just screw around with the code for a while and see what I could get to. This worked:
private static BlockingQueue<String> queue;
private BlockingQueue<String> getQueue() {
if (queue == null) {
queue = new LinkedBlockingQueue<String>();
}
return queue;
}
As Yanick Rochon pointed out the code could be simplified slightly by using a BlockingQueue instead of an ordinary Queue, but the change that made the difference was that I implemented the Singleton pattern.
As this solves my immediate problem to get the app working, I'll call this the answer. Large amounts of kudos should go to #Fly and others for pointing out that the Queue instances might not be the same - without that I would never have figured this out. However, I'm still very curious on why I have to do it this way, so I will ask a new question about that in a moment.
I am writing a simple threading application. Thread is simply a message consumer and process it. However, if the thread somehow got interrupted and the message is not fully processed, I want to put it back to the queue and let other instances get it. So I had to code it like this:
public void run()
{
Map<String, String> data = null;
try
{
while(true)
{
data = q.getData();
System.out.println(this+" Processing data: "+data);
// let others process some data :)
synchronized(this){
sendEmail(data);
data = null;
}
}
}
catch (InterruptedException e)
{
System.out.println(this+" thread is shuting down...");
if(null!=data)
q.add(data);
}
}
Thanks...
EDIT: Thanks for the responses. Everything is very clear now. I understand that even when lines of codes are in a synchronized block, if any of them can throw InterruptedException then it simply means they can be interrupted at that point. The line q.getData() enters this thread to a 'blocked' state (I am using LinkedBlockedQueue inside the q.getData()). At that point, this thread can be interrupted.
A thread will not catch an InterruptedException any time another thread calls interrupt() on it, nor does that method magically stop whatever it's doing. Instead, the method sets a flag that the thread can read using interrupted(). Certain other methods will check for this flag and raise InterruptedException if it's set. For example, Thread.sleep() and many I/O operations which wait for an external resource throw it.
See the Java Thread Interrupts Tutorial for more information.
In addition to David Harkness's answer: you also don't understand meaning of synchronized keyword.
Synchornized is not a kind of "atomic" or "uninterruptable" block.
Synchornized block doesn't provide any guarantees other than that other threads can't enter synchronized block on the same object (this in your case) at the same time (+ some memory consistency guarantees irrelevant in your case).
Therefore usage of synchornized in your case is pointless, since there is no need to protect data from concurrent access of other threads (also, you are synchronizing on this, I don't think other threads would synchronize on the same object).
See also:
Synchronization
Ignoring for the moment that while(true) puts the thread into a CPU loop...
If sendMail does anything that checks for thread interruption it will throw an interrupted exception. So the answer to your question is likely to be a solid yes, the thread can be interrupted within the synchronized block, and you will have to catch the exception and check for that.
That said, InterruptedException is a checked exception, so short of funny buggers being done at a lower level, sendMail should indicate that it can throw InterruptedException.
Yes
Java synchronization means no other thread can access the same lock while a thread has acquired it.
If you don't want any other thread to be able to access a message (or any other object) use synchronized(message) block.
Q1. What is a condVar in Java? If I see the code below, does a condition variable necessarily have to be within the 'mutex.acquire()' and 'mutex.release()' block?
public void put(Object x) throws InterruptedException {
mutex.acquire();
try {
while (count == array.length)
notFull.await();
array[putPtr] = x;
putPtr = (putPtr + 1) % array.length;
++count;
notEmpty.signal();
}
finally {
mutex.release();
}
}
I have three threads myThreadA, myThreadB, myThreadC running which call the same function commonActivity() which triggers the function myWorkReport() e.g.
public void myWorkReport(){
mutexMyWork.acquire();
try{
while(runMyWork){
doWork();
conditionMyWork.timedwait(sleepMyWork);
}
}
finally{
mutexMyWork.release()
}
}
public void commonActivity(){
try{
conditionMyWork.signal();
}finally{
//cleanup
}
}
public void myThreadA(){
mutexA.acquire();
try{
while(runningA){ //runningA is a boolean variable, this is always true as long as application is running
conditionA.timedwait(sleepA);
commonActivity();
}
}
finally{
mutexA.release();
}
}
public void myThreadB(){
mutexB.acquire();
try{
while(runningB){ //runningB is a boolean variable, this is always true as long as application is running
conditionB.timedwait(sleepB);
commonActivity();
}
}
finally{
mutexB.release();
}
}
public void myThreadC(){
mutexC.acquire();
try{
while(runningC){ //runningC is a boolean variable, this is always true as long as application is running.
conditionC.timedwait(sleepC);
commonActivity();
}
}
finally{
mutexC.release();
}
}
Q2. Is using timedwait a good practice. I could have achieved the same by using sleep(). If using sleep() call is bad, Why?
Q3. Is there any better way to do the above stuff?
Q4. Is it mandatory to have condition.signal() for every condition.timedwait(time);
Q1) The best resource for this is probably the JavaDoc for the Condition class. Condition variables are a mechanism that allow you to test that a particular condition holds true before allowing your method to proceed. In the case of your example there are two conditions, notFull and notEmpty.
The put method shown in your example waits for the notFull condition to become true before it attempts to add an element into the array, and once the insertion completes it signals the notEmpty condition to wake up any threads blocked waiting to remove an element from the array.
...does a condition variable necessarily
have to be within the
'mutex.acquire()' and
'mutex.release()' block?
Any calls to change the condition variables do need to be within a synchronized region - this can be through the built in synchronized keyword or one of the synchronizer classes provided by the java.util.concurrent package such as Lock. If you did not synchronize the condition variables there are two possible negative outcomes:
A missed signal - this is where one thread checks a condition and finds it does not hold, but before it blocks another thread comes in, performs some action to cause the condition to become true, and then signals all threads waiting on the condition. Unfortunately the first thread has already checked the condition and will block anyway even though it could actually proceed.
The second issue is the usual problem where you can have multiple threads attempting to modify the shared state simultaneously. In the case of your example multiple threads may call put() simultaneously, all of them then check the condition and see that the array is not full and attempt to insert into it, thereby overwriting elements in the array.
Q2) Timed waits can be useful for debugging purposes as they allow you to log information in the event the thread is not woken up via a signal.
Using sleep() in place of a timed wait is NOT a good idea, because as mentioned above you need to call the await() method within a synchronized region, and sleep() does not release any held locks, while await() does. This means that any sleeping thread will still hold the lock(s) they have acquired, causing other threads to block unnecessarily.
Q4) Technically, no you don't need to call signal() if you're using a timed wait, however, doing so means that all waits will not return until the timeout has elapsed, which is inefficient to say the least.
Q1:
A Condition object is associated (and acquired from) a Lock (aka mutext) object. The javadoc for the class is fairly clear as to its usage and application. To wait on the condition you need to have acquired the lock, and it is good coding practice to do so in a try/finally block (as you have). As soon as the thread that has acquired the lock waits on a condition for that lock, the lock is relinquished (atomically).
Q2:
Using timed wait is necessary to insure liveness of your program in case where the condition you are waiting for never occurs. Its definitely a more sophisticated form, and it is entirely useless if you do not check for the fact that you have timed out and take action to handle the time out condition.
Using sleep is an acceptable form of waiting for something to occur, but if you are already using a Lock ("mutex") and have a condition variable for that lock, it make NO sense not to use the time wait method of the condition:
For example, in your code, you are simply waiting for a given period but you do NOT check to see if condition occurred or if you timed out. (That's a bug.) What you should be doing is checking to see if your timed call returned true or false. (If it returns false, then it timed out & the condition has NOT occured (yet)).
public void myThreadA(){
mutexA.acquire();
try{
while(runningA){ //runningA is a boolean variable
if(conditionA.await (sleepATimeoutNanos))
commonActivity();
else {
// timeout! anything sensible to do in that case? Put it here ...
}
}
}
finally{
mutexA.release();
}
}
Q3: [edited]
The code fragments require a more detailed context to be comprehensible. For example, its not entirely clear if the conditions in the threads are all the same (but am assuming that they are).
If all you are trying to do is insure commonActivity() is executed only by one thread at a time, AND, certain sections of the commonActivity() do NOT require contention control, AND, you do require the facility to time out on your waits, then, you can simply use a Semaphore. Note that sempahore has its own set of methods for timed waits.
If ALL of the commonActivity() is critical, AND, you really don't mind waiting (without timeouts) simply make commonActivity() a synchronized method.
[final edit:)]
To be more formal about it, conditions are typically used in scenarios where you have two or more thread co-operating on a task and you require hand offs between the threads.
For example, you have a server that is processing asynchronous responses to user requests and the user is waiting for fulfillment of a Future object. A condition is perfect in this case. The future implementation is waiting for the condition and the server signals its completion.
In the old days, we would use wait() and notify(), but that was not a very robust (or trivially safe) mechanism. The Lock and Condition objects were designed precisely to address these shortcomings.
(A good online resource as a starting point)
Buy and read this book.
Q1. Condition variables are part of monitors facility which is sometimes used for threads synchronization. I don't recognize this particular implementations but usually conditional variables usage must be done in the critical section, thus mutex.acquire and release are required.
Q2. timedwait waits for signal on condition variable OR time out and then reqcquires critical section. So it differs from sleep.
Q3. I am not sure, but I think you may use built-in monitors functionality in java: synchronized for mutual exclusion and wait and notify instead of cond vars. Thus you will reduce dependencies of your code.
Q1. I think documentation gives quite good description. And yes, to await or signal you should hold the lock associated with the condition.
Q2. timedWait is not in Condition API, it's in TimeUnit API. If you use Condition and want to have a timeout for waiting use await(long time, TimeUnit unit). And having a timeout is generally a good idea - nobody wants a program to hang forever - provided you know what to do if timeout occurs.
Sleep is for waiting unconditionally and await is for waiting for an event. They have different purposes.
Q3. I don't know what this code is expected to do. If you want to perform some action cyclically, with some break between each iteration, use sleep instead of conditions.
Q4. As I wrote above conditions don't have timedwait method, they have await method. And calling await means you want to wait for some event to happen. This assumes that sometimes this event does happen and someone signals this. Right?
Q1. I believe by "condition variable", you're referring to something you check to determine the condition that you waited on. For example - if you have the typical producer-consumer situation, you might implement it as something like:
List<T> list;
public T get()
{
synchronized (list)
{
if (list.get(0) == null)
{
list.wait();
}
return list.get(0);
}
}
public void put(T obj)
{
synchronized (list)
{
list.add(obj);
list.notify();
}
}
However, due to the potential of spurious thread wakeups, it is possible for the consumer method to come out of the wait() call while the list is still empty. Thus it's good practice to use a condition variable to wait/sleep/etc. until the condition is true:
while (list.get(0) == null)
{
list.wait();
}
using while instead of if means that the consumer method will only exit that block if it definitely has something to return. Broadly speaking, any sleep or wait or blocking call that was triggered by a condition, and where you expect the condition to change, should be in a while block that checks that condition every loop.
In your situation you're already doing this with the while (count == array.length) wrapper around notFull.await().
Q2. Timed wait is generally a good practice - the timeout allows you to periodically perform a sanity check on your environment (e.g. has a shutdown-type flag been flipped), whereas a non-timed wait can only be stopped by interruption. On the other hand, if the wait is going to just keep blocking anyway until the condition is true, it makes little difference it it wakes up every 50 ms (say) until the notify() happens 2 seconds later, or if it just blocks constantly for those 2 seconds.
As for wait() vs sleep() - the former is generally preferable, since it means you get woken up as soon as you are able to take action. Thread.sleep(500) means that this thread is definitely not doing anything for the next 500ms, even if the thing it's waiting for is ready 2ms later. obj.wait(500) on the other hand would have been woken up 2ms into its sleep and can continue processing. Since sleeps introduce unconditional delays in your program, they're generally a clunkier way to do anything - they're only suitable when you're not waiting on any specific condition but actually want to sleep for a given time (e.g. a cleanup thread that fires every 60 seconds). If you're "sleeping" because you're waiting for some other thread to do something first, use a wait() (or other synchronous technique such as a CountDownLatch) instead.
Q3. Pass - it looks like there's a lot of boilerplate there, and since the code doesn't have any comments in and you haven't explained what it's supposed to do and how it's meant to behave, I'm not going to try and reverse-engineer that from what you're written. ;-)