Whenever I write Thread.sleep(500); in my code, it always tells me this sometimes causes problems to use Thread.sleep();. Is there another way to delay time before certain things. If so, can you give me the code and explanation. Thank you
Firstly, you don't show us any code and you don't mention what "it" is. (As in "it always tells me ...".) This makes a specific answer impossible.
It most likely that the problem referred to is that sleep makes your code either wasteful or unresponsive. A common "hack" used to make a thread wait for some condition is to repeatedly call sleep and then test the condition. The problem is that if the condition becomes true while you are sleeping, the thread will still be held up until the sleep interval expires. If you make the sleep interval smaller, then you "burn" more CPU cycles with wakeup / test / sleep iterations.
If you are trying to implement a "wait for some condition to become true", then the efficient way to do it is to either use wait() and notify() (or notifyAll()), or an appropriate higher level synchronization class.
The classic Java pattern is like this:
// waiting for the condition
synchronized (obj) {
while (!condition) {
obj.wait();
}
}
...
// updating the condition ...
synchronized (obj) {
// do something that makes condition true
obj.wait();
}
Note that the use of synchronized is essential if you use wait/notify.
Condition interface can be useful to let other threads notify you about specific events and ask the current thread to get "parked" till then. Condition interface also has a methods called waitUntil(Date deadline) - which causes current thread to wait until the deadline elapses.
Are you waiting for some other thread to perform some activity and wait till then? Use any blocking data structure like BlockingQueue or other advanced synchronizers like CountdownLatch.
If just waiting for some thread to complete its execution use join().
As mentioned bay MadProgrammer and alfasin, its important to know what you are trying to achieve and what is the problem in sleep() you are talking about.
If you want something to happen in the near future, using sleep repeatedly is a bad thing. For once it does not guarantee to be "on time", and for second it can be interrupted at any time, causing your program to malfunction.
If you have one part of your code that needs to be executed repeatedly, using a Timer can solve that perfectly. If you have multiple and different parts of code that need to be executed with given delays, you should use a ScheduledExecutorService. You can either use the ScheduledThreadPoolExecutor directly or - more conveniently - use the ExecutorService.
You can easily circumvent threading issues by just using a single thread. However threading isn't that difficult in Java if you use the right tools.
Related
I was reading about ways to end a thread in https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html, which is a link I found from the question How do you kill a thread in Java?
In the first link, they first discuss using a volatile variable to signal to the thread that you want to terminate. The thread is supposed to check this variable and cease operation if the variable has a value that means cease (e.g. if it is null). So to terminate the thread, you would set that variable to null.
Then they discuss adding interrupts to help with threads that block for long periods of time. They give the following example of a stop() method that sets the volatile variable (waiter) to null and then ALSO throws an interrupt.
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}
I am just wondering, why would you need both? Why not ONLY use interrupt(), and then handle it properly? It seems redundant to me.
(First part of this is in general, arguably I was not paying attention to the specifics of the question. Skip to the end for the part that addresses the techspec discussed in the question.)
There is no good technical reason. This is partly about human limitations and partly about confusing api design.
First consider application developers’ priority is creating working code that solves business problems. Thoroughly learning low level apis like this gets lost in the rush to get work done.
Second there’s a tendency when you’re learning things to get to a good enough state and leave it there. Things like threading and exception handling are back-of-the-book topics that get neglected. Interruption is a back of the book topic for threading books.
Now imagine a codebase worked on by multiple people with varying skill level and attention to detail, who may forget that throwing InterruptedException from wait and sleep resets the interrupt flag, or that interrupted isn’t the same as isInterrupted, or that InterruptedIoException resets the interrupt flag too. If you have a finally block that catches IOException, you may miss that InterruptedException is a subclass of IOException and you could be missing out on restoring the interrupt flag. Probably people in a hurry decided to hell with it, I can’t count on this interrupted flag
Is it right? No.
The hand rolled flag doesn’t help with short circuiting wait or sleep the way interruption does.
the Java 5 concurrency tools expect tasks to use interruption for cancellation. Executors expect tasks submitted to them to check for interruption in order to quit gracefully. Your tasks may use other components, like a blocking queue. That queue needs to be able to respond to interruption, the thing using it needs to be aware of the interruption. The handrolled flag doesn’t work for this since the java 5 classes can’t know about it.
Having to use interruption because you’re using tools that expect it, but not having confidence in the flag value due to unmanageable technicalities, would lead to this kind of code.
(end of rant, now actually responding to the specific techspec example)
OK, looking at this techguide article in particular. Three things stand out:
1) it's not making use of interruption at all, except to cut the sleep time short. Then it just squelches the exception, and doesn't bother to restore the flag or check it. You could use the InterruptedException to terminate by catching it outside the while loop, but that's not what this does. This seems like a strange way to do this.
2) as the example is fleshed out it becomes clear the flag is being used to turn the waiting on and off. Somebody might use interruption for this but it's not idiomatic. So having a flag is ok here.
3) this is a toy example in a techguide. Not all the Oracle content is as authoritative as the techspecs or the API documentation. Some tutorials have misstatements or are incomplete. It might be the reason the code was written like this was that the author figured readers would not be familiar with how interruption worked and it was better to minimize its usage. Technical writers have been known to make choices like that.
If I rewrote this to use interruption I would still keep the flag; I'd use interrupt to terminate, and use the flag for suspend/resume functionality.
Please see this documentation.
Your thread should check thread.isInterrupted() status, for example:
Thread myThread = new Thread() {
#Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("I'm working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//We would like also exit from the thread
return;
}
}
}
};
And when you would like to stop the thread, you should invoke
myThread.interrupt();
Besides we can use static method Thread.interrupted() that also checks the status but after that, the method clears it and you have to invoke again myThread.interrupt() to set the status again. But I don't recommend to use Thread.interrupted() method.
This approach helps gracefully stop the thread.
So I also do not see any reasons to use an additional volatile variable.
The same behavior can be reached via additional volatile flag as in #lexicore's answer, but I think it is redundant code.
#NathanHughes is completely right, but I am going to rephrase his long answer into few words: third-party code.
This is not just about "dumb junior developers", — at some point in application's life you will be using lots of third-party libraries. Those libraries will not gentlemanly respect your assumptions about concurrency. Sometimes they will silently reset interruption flag. Using separate flag solves that.
No, you can not get rid of third-party code and call it a day.
Suppose, that you are writing a library, — for example, ThreadPoolExecutor. Some of the code inside your library needs to handle interruption… Or even unconditionally reset the interruption flag. Why? Because previous Runnable is done, and a new Runnable is on the way. Unfortunately, at that point there may be a stale interruption flag, that was aimed… wait, whom was it for again? It could have been addressed for previous Runnable or for new (not yet running) Runnable, — there is no way to tell. And this is why you add isCancelled method to FutureTask. And unconditionally reset interruption flag before executing new Runnable. Sounds familiar?
Thread#interrupt is completely detached from the actual work units, running on that thread, so adding an additional flag is necessary. And once you have started doing so, you have to do that all the way — up to the outermost and down to the innermost work unit. In effect, running unknown user-supplied code on your threads makes Thread#interrupted unreliable (even if Thread#interrupt still works fine!)
I have a ReentrantLock in my code and want to use it to clear an array once per second; I dont want other threads to change the array while it is being cleared, but if I am not currently clearing the array other threads shall not have to wait, like this:
public void addToArray(Object a) {
lock.waitforunlock(); //not a real method just to clarify my intentions
array.add(a);
}
To better clarify my intentions I will explain the process: the netty eventloop will call my network handler, that network handler will then call the addToArray method from before, once per second my main thread that will never be a Netty thread will clear the array, in this time every netty thread shall have to wait until this is finished! Note: the addToArray method is threadproof and I dont want to sync it because then the hole point of a event loop is useless.
There is no API method that does exactly what you are asking.
The most efficient way to do it is like this:
try {
lock.lock();
} finally {
lock.unlock();
}
In other words, grab the lock momentarily then release it.
But here's the problem.
In general, the instant you release the lock, some other thread might immediately grab it. So your array.add() call may happen simultaneously with some other thread doing things to array. Even if your use-case means that another thread grabbing the lock is highly unlikely, it can still happen; e.g. if your server is under severe load and the current thread gets preempted immediately after releasing the lock.
Presumably you are performing memory writes in array.add(). Unless they are performed with appropriate synchronization, those updates may not be visible to other threads. (You say "addToArray method is threadproof", but without a clear, detailed explanation of what you mean by that, I would be uncomfortable with saying this code is thread safe.)
If what you are trying to do here is to array.add() after something else has happened, then testing the lock / waiting for it to be released doesn't tell you if the event actually happened. All it tells you is that it wasn't happening at the instant that the test succeeded.
In short, I doubt that waiting for a lock to be released before doing an update is actually a correct solution ... no matter how you implement the waiting.
Another way to look at this.
If array.add() is completely threadsafe, and will work correctly irrespective of some other thread holding the lock, why do you need to test the lock? Just call the method.
If you are actually trying to have the array.add() call happen after some event that coincides with the lock being released, use a cyclic barrier or similar.
Note: I read and tried to understand your explanation, but I got lost with what you are saying. Due to "language issues" I think.
As I understand it, you have two or more separate threads mutating a list: the main thread occasionally clearing the list, and the netty thread adding to the list. You want to make sure they don't both attempt to modify the list at the same time.
The simplest solution to this is to use a thread safe list, and make sure the main thread uses the List.clear() method to clear the list. That way, the clear() call will be atomic - once started it will finish before any other accesses to the list - so you won't have to worry about adding to the list "in the middle of" the clear() call.
In a comment to another answer, you mention that you are using a CopyOnWriteArrayList, which is thread safe. Thus, you can just call add() the code that adds to the list without worrying about synchronization; the add() call will automatically wait if the list is being cleared, and proceed otherwise. You can also remove the use of the ReentrantLock from your main thread unless there are other reasons, besides protecting this list, to use the lock.
Hi I'm pretty new to Java and now I'm getting into java concurrency. And I have a little doubt about Synchronized methods: i have seen that I can get the same results using an If else inside a Synchronized method, checking every time If the condition to do an action is fullfilled, as using a wait / notify approach.
Since i get the same result I'm wondering If the If else approach has any advantages or disadvantages over t'he wait and notify approach? I supose that efficiency will be a disadvantage, since If is always checking the condition, Who le wait Just stops and waits for notify. But are any other advantages or disadvantages?
Thx!
You are mixing two concepts. If-Else vs Wait-Notify are totally different. You want two threads to communicate with each-other that is where Wait-Notify would be used while if-else is general conditional statement.
You cannot have two threads communicate with each other simply using if-else condition. You can write your code that makes it look like it does however you are simply not allowing threads to interact with each other.
Moreover it can lead to undesirable consequences/computational states. Sooner or later you would have hotchpotch code.
synchronized block makes the code thread safe. You would want to use wait() and notify() or notifyAll() if you want to be more efficient.
For example if your shared resource is a list, multiple threads share. If you put it in synchronized block of a monitor then threads will constantly jump in and run the code, during context switches. Even if the list is enpty!!
The wait() is hence used on the monitor (the object inside the synchronized(..)) as a mechanism to 'tell' all threads to chill out and stop using CPU cycles until further notice or notifyAll().
synchronized(monitor) {
while( list.isEmpty() )
monitor.wait();
doSomething(...)
}
In the above example, doSomething() will be executed only when the list is not empty, after another thread executed notify() or notifyAll() somewhere else in the code.
read more why use while surrounding wait()
BUT with the following code:
synchronized(monitor) {
if(!list.isEmpty())
doSomething(...)
}
When a thread comes in to the synchronized block, there are 3 possible scenarios:
The list is empty: doSomething() will not be executed.
The list is NOT empty: doSomething() may be executed properly, or...
If there was a context switch right after the if and before doSomething, and the other thread got all list's items out, after another context-switch out thread will execute doSomethig() on an empty list.
So, just to sum everything up, if you use wait/notify, you guarantee more efficient code! thread will not work when they don't need to.
I am trying to stop a current thread, change the run() method, and then restart that thread. I've looked around, and most of the methods are deprecated. However, interrupt() is not. I'm not sure if that's all you need to do.
interrupt();
start();
Would that work for what I needed it to do? It says that you should never start a thread more than once, and I don't know if it means
start();
start();
Rather than what I wanted to do.
Any help is appreciated.
Thanks
No, you can't do that. Fron the java online docs:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Don't restart a thread. You ALWAYS can rewrite your buisness logic to do this some other way. Consider using SingleThreadExecutor
In this case, you should create a Runnable object and pass it to a thread. Then you're creating different threads, but re-using the 'work' object.
Once you've started a thread, you can only interrupt it. Once you've done that, you can't start it again. See here for more details.
I'm not quite sure what you want to do, but it sounds like you have different Runnables that you want to run in sequence. In this case use a SingleThreadExecutor and submit your Runnables. It will run these in order, and so interrupting the first (successfully) will invoke the second.
I'm still not sure this is a good idea (it just doesn't sound right) and perhaps posting a more detailed problem description will give people a better idea of what you're really trying to do.
You should look into the basics of threading more. A thread can only run once. If you want to have the thread run different code, you need to create a new thread.
The interrupt() method will not stop a thread immediately (there is no supported) way to do that, it will stop only at certain points by throwing an InterruptedException().
I think you're approaching your problem in the wrong way. You cannot 'change the run() method of a Thread'. However what you probably want is to stop the previous thread and create a new one with a different run() method.
One thing to keep in mind however, is that Threads are designed to be as autonomous as possible and they don't like interference from other threads, which is why suspend() and resume() are deprecated. They create all sorts of bad behaviour depending on the circumstances and also prone to deadlocks.
You have 2 perfectly safe alternatives however:
Use wait() and notify() on a specific shared object.
Use sleep() and interrupt()
You need to decide within the run() method where it is safe to 'stop' the thread, and at that point put a wait() or sleep(). Your thread will only stop at that point.
The other thread can then do a notify() or sleep() so that the running thread is notified or interrupted. In case of interrupt() you will get an InterruptedException which you can use to terminate what you were doing in that thread.
After interrupting the old thread you can start a new thread initialised with a new Runnable implementation which has the different run() method.
Calling interrupt() will set the thread's interrupt status potentially interrupting blocking methods. This is part of a cooperative cancellation mechanism. You can't use it to force the thread to stop running.
Stopping threads has been deprecated for a reason: it is inherently dangerous as it may leave the state variables which it is manipulating in an inconsistent state.
You should not do this. Make your code from the run() method into a Runnable and submit it for execution to an Executor. This will return you a Future which you can use to retrieve its results as well as to cancel it.
If you want to reuse the same thread for other computations, use a thread pool, see for example Executors.newFixedThreadPool() and other factory methods in Executors.
I'm doing a code review for a change in a Java product I don't own. I'm not a Java expert, but I strongly suspect that this is pointless and indicates a fundamental misunderstanding of how synchronization works.
synchronized (this) {
this.notify();
}
But I could be wrong, since Java is not my primary playground. Perhaps there is a reason this is done. If you can enlighten me as to what the developer was thinking, I would appreciate it.
It certainly is not pointless, you can have another thread that has a reference to the object containing the above code doing
synchronized(foo) {
foo.wait();
}
in order to be woken up when something happens. Though, in many cases it's considered good practice to synchronize on an internal/private lock object instead of this.
However, only doing a .notify() within the synchronization block could be quite wrong - you usually have some work to do and notify when it's done, which in normal cases also needs to be done atomically in regards to other threads. We'd have to see more code to determine whether it really is wrong.
If that is all that is in the synchonized block then it is an antipattern, the point of synchronizing is to do something within the block, setting some condition, then call notify or notifyAll to wake up one or more waiting threads.
When you use wait and notify you have to use a condition variable, see this Oracle tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
You shouldn't assume you received a notification just because a thread exited from a call to Object#wait, for multiple reasons:
When calling the version of wait that takes a timeout value there's no way to know whether wait ended due to receiving a notification or due to timing out.
You have to allow for the possibility that a Thread can wake up from waiting without having received a notification (the "spurious wakeup").
The waiting thread that receives a notification still has to reacquire the lock it gave up when it started waiting, there is no atomic linking of these two events; in the interval between being notified and reacquiring the lock another thread can act and possibly change the state of the system so that the notification is now invalid.
You can have a case where the notifying thread acts before any thread is waiting so that the notification has no effect. Assuming one thread will enter a wait before the other thread will notify is dangerous, if you're wrong the waiting thread will hang indefinitely.
So a notification by itself is not good enough, you end up guessing about whether a notification happened when the wait/notify API doesn't give you enough information to know what's going on. Even if other work the notifying thread is doing doesn't require synchronization, updating the condition variable does; there should at least be an update of the shared condition variable in the synchronized block.
This is perfectly fine. According to the Java 6 Object#notify() api documentation:
This method should only be called by a thread that is the owner of this object's monitor.
This is generally not a anti-pattern, if you still want to use intrinsic locks. Some may regard this as an anti pattern, as the new explicit locks from java.util.concurrent are more fine grained.
But your code is still valid. For instance, such code can be found in a blocking queue, when an blocking operation has succeeded and another waiting thread should be notified. Note however that concurrency issues are highly dependent on the usage and the surrounding code, so your simple snippet is not that meaningful.
The Java API documentation for Object.notify() states that the method "should only be called by a thread that is the owner of this object's monitor". So the use could be legitimate depending upon the surrounding context.