UPDATE:
Turns out there wasn't anything wrong with my Synchronized statements. I made a mistake earlier on in the code and it was blocking there. I apologize for the wasted time and thank you for all the help.
PS. The CountDownLatch suggested by #sh0rug0ru was better suited to my needs and was exactly what I needed.
PREVIOUS:
This is the relevant part of the code:
synchronized (readyLock) { //sets this thread's status to ready
readyLock.notify();
System.out.println("notify works");
try {
readyLock.wait();
System.out.println("woke up from sleep");
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(Level.SEVERE, null, ex);
}
readyLock.notify();
}
while (true) { //game loop
//Some stuff here
synchronized (readyLock) { //sets this thread's status to ready
readyLock.notify();
System.out.println("notify works");
try {
readyLock.wait();
System.out.println("woke up from sleep");
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(Level.SEVERE, null, ex);
}
readyLock.notify();
}
//Some more stuff here
}
The readyLock object is initialized in another class as a static final variable:
static final Object readyLock = new Object();
The Synchronized statement works the first time, as in the first synchronized block of statements. But the synchronized block inside the while loop doesn't work. It's the exact same code in both the places.
This class is a thread that is run twice from a server. It's for a two player game. The rest of the code is here.
I'm trying to figure out why the second synchronized statement doesn't work. I think it's just blocking there for some reason.
NOTE All the System.out.println(""); lines are for debugging.
When you use notify(), this would come with a state change.
When you wait() you should check for that state change.
Otherwise you risk either;
the notify is lost if nothing is waiting at that moment.
wait can wake spuriously.
This is covered in the documentation for those methods.
Don't use notify, use notifyAll. notify will pick a random waiting thread. If that thread goes back to wait state and notify isn't called again, all the other waiting threads will stay waiting, and you have yourself a deadlock.
Using notifyAll will give all threads in wait state a chance to proceed.
notify is very dangerous, and there is almost no good reason to use it.
Better yet, why are you using wait/notify/notifyAll in the first place? What are you trying to achieve? Whatever concurrency pattern you are trying to implement probably already has an implementation in java.util.concurrent which will more clearly and more safely do whatever it is you are trying to do.
As I said in comments, the second notify() in each synchronized block is suspicious. If the purpose for wait()ing is to make the two threads you describe take turns, so that only one runs at any given time, then your code is broken. Here's what then actually happens:
One thread enters the (one of the) synchronized blocks, excluding all others.
That thread notifies one other blocked waiting on readyLock, if there is any, so that it can proceed when the current thread releases that monitor.
The current thread blocks, releasing the monitor and await a notification of its own.
The other thread does its thing, until it comes to the same or a similar block, at which time it notifies the waiting thread and thereafter itself begins waiting.
The original thread proceeds, immediately notifying the waiting thread.
The original thread exits the synchronized block, releasing the readyLock's monitor
The second thread can then return from wait(), running concurrently with the first.
In itself, that does not explain a deadlock, but if you don't expect the two threads to be running concurrently then there's any number of ways trouble could ensue.
Here's how you might structure that scenario better:
synchronized (readyLock) {
setMyTurn(false);
otherPlayer.setMyTurn(true);
readyLock.notify();
while (!isMyTurn()) {
try {
readyLock.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(
Level.SEVERE, null, ex);
}
}
}
Note that you might want to consider notifyAll() instead of notify(). The distinction doesn't matter if there can be only one other thread waiting on the monitor, but it is otherwise safer if all potential waiters utilize a loop and condition check as shown.
Related
I have this simple code, it's simply a testing case
try
{
synchronized(this) {
while(number != 4)
{
System.out.println("Waiting...");
this.wait();
}
number = 4;
this.notifyAll();
}
}
catch(InterruptedException e)
{}
Of what I know regarding use of the wait() method, once wait is invoked, what comes after should be done. However I can't see to get the wait to end in this case. I have attempted to place a second synchronized block but that doesn't seem to work.
Do you know what could be causing the wait to hang? I looked up deadlocking but that seems to be an entirely different matter.
Think u better get some idea from here
then modify your code accordingly, as long there is no another thread is running.
The wait() method causes the current thread to wait indefinitely until another thread >either invokes notify() for this object or notifyAll().
Do you know what could be causing the wait to hang?
You have a loop that's waiting for number to be set to 4. No code is executed that sets number to 4. Therefore the loop waits forever.
while(number != 4)
{
System.out.println("Waiting...");
this.wait();
}
/* you can't get here until some other thread sets number to 4. */
number = 4;
this.notifyAll();
}
The wait call does not terminate until some other code calls notify, and then when you wake up out of the wait, you'll loop back again unless number is now 4.
You can't have a thread simultaneously be in wait and executing the code that issues the notify. And if wait didn't wait, it would not be useful.
Not intending to be rude, but the problem here seems to be a lack of understanding of sequential execution of program code.
I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:
while(true) {
try {
synchronized(t) {
t.wait();
}
} catch(InterruptedException e) {
break;
}
}
And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?
Summary
So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.
Alternative
Lets step through a brief, simplified example.
Object obj = new Object;
synchronized (obj) {
while(condition) {
obj.wait();
}
}
A thread here will obtain the monitor.
The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.
Lets investigate how we go about returning the thread to work.
synchronized(obj) {
obj.notify();
}
The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.
Say i've got the following code:
public void run(){
while (true){
function1();
...
functionN();
}
}
And i wanna exit 'gracefully' - Which means for me that once i sent a shutdown signal and currently the thread is at functionK(), The thread will 'break' the loop and exit run.
So i've tried using Thread.interrupt() like this:
public void run(){
while (true){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
But this doesn't work - The thread continutes to run endlessly even with interrupt flag on.
Just for the record:
public void run(){
while (!thread.isInterrupted()){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
Stops the loop, But doesn't help me. Since each function does something that might take several minutes and there are a lot of different function so checking before each function whether interrupted flag is one might be costly (Especially since most of the times the application runs smoothly).
I wonder whether there is a special mechanism i can use for that kind of problem.
The API documentation is very clear about this:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
So you can only rely on this exception if you're waiting for object monitors. There are a couple of other exceptions thrown by certain I/O operations but if you don't use them either, there is no other option than to check the interrupted() flag.
What you can do though is to re-organise your code: if you've got N methods that are called one after the other, is it not possible to abstract them out into a loop? More often than not it is possible to find a way to refactor code to support interruption, the exact way depends on your actual scenario. My first question would be: why does a single method run for minutes? That sounds a bit fishy (though it may be justified).
Either way, interruptibility isn't something that comes for free, you have to actively design interruption points if you want your code to be more responsive to interruption than the length of the main loop.
One more thing though: checking the interrupted() flag is most definitely NOT costly. Not when you spend minutes in your main loop, and it's a lot cheaper than constructing and handling an exception. I'd go as far as to say that you'll find very few things faster than a call to Thread.isInterrupted().
Actually if you are doing CPU bound work in your methods, you have to check for Thread.interrupted() by yourself and throw InterruptedException yourself. Java won't magically do it for you, unless you park at some specifically designed spaces, such as Semaphore.wait() etc.
Your second example will keep looping after the interrupt. This is because InterruptedException doesn't actually mean that the Thread's interrupted flag is set; in fact, you don't need to check it at all.
To fix this, you can simply re-interrupt the thread (to allow callers to know that the thread was interrupted), and then break:
public void run(){
while (true) {
try {
function1();
//...
functionN();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
}
As stated in the book "Java concurrency in Practice" :"Java does not provide any mechanism for safely forcing a thread to stop what is doing", so you must implement something on your side. checking the interrupted flag and handling the InterruptedException is the best way to manage thread cancellation.
If one of you function1()...functionN() is in the middle of a database transaction or a HTTP call is up to your program to handle the cancellation; you can wait until to n seconds and save the current state or cancel the transaction and roolback, the action to perform is dictated by your application logic.
In a first Java thread I have:
while (!isDone) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
doSomeVeryLongRunningTask();
}
In another thread, I want to send a notify signal:
synchronized (thr1) {
thr1.notify();
}
However, if the doSomeVeryLongRunningTask() method is running, I don't want the second thread to get blocked. I only want to notify the first thread if it is waiting so that the second thread can continue it tasks without getting locked.
How might I fix the code above to accomplish this?
They problem you want to fix does not exist. synchronized blocks will block the thread only if another thread is already inside a synchronized block synchronizing on the same object. Since your doSomeVeryLongRunningTask() will be called outside the synchronized block the notifying thread will never get blocked if the other thread is inside the doSomeVeryLongRunningTask() method.
But this raises another problem. You seem to be thinking, that wait and notify invocations are always paired. This is not the case, you may call notify as often as you wish without anyone listening to it. It might be also the case that a wait invocation returns “spuriously”, i.e. for no apparent reason. You therefore need to define another “hard condition” which is defined by a state that is modified and checked inside the synchronized block.
E.g. inside the class whose instance you have in your thr1 variable, you can define a boolean flag:
boolean condition;
Then you modify you waiting method like this:
while(!isDone) {
try {
synchronized(this) {
while(!condition) wait();
if(isDone) break;// skip doSomeVeryLongRunningTask()
condition=false;
}
} catch(InterruptedException e) {
e.printStackTrace();
}
doSomeVeryLongRunningTask();
}
And the notifying code to:
synchronized(thr1) {
thr1.condition=true;
thr1.notify();
}
This way your notifying code still won’t get blocked (at least never for a significant time) but the waiting thread will wait for at least one notification to happen within one loop cycle.
It seems what is blocking your program is not the notify() (it doesn't block ever) but the two synchronized blocks that are synchronizing on the same object.
I don't think there is a workaround to what you ask. Check this link to know why: http://javarevisited.blogspot.com/2011/05/wait-notify-and-notifyall-in-java.html
The notify() call doesn't block. Only wait() blocks. You can call notify even if there isn't another thread waiting, but then make sure your algorithm is correct. If you expect to notify only once, then another thread arriving after the notify will wait() forever.
The advised pattern is to use notifyAll() AND to have ALL waiting threads check their wake-up condition each time they are notified AND before starting the first Wait.
The synchronized in modern Java is about as fast as --i, because this is about what is internally happening thanks to hardware compareAndSet mechanisms. The only moment this slows down noticeably, is when more than one thread is arriving at the synchronized block and therefore at least one has to wait.
Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged