I have a worker thread running indefinitely, which goes to sleep for one minute if there's nothing to do. Sometimes, another piece of code produces some work and wants to wake the worker thread immediately.
So I did something like this (code for illustration only):
class Worker {
public void run() {
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
if (hasWork()) {
doIt();
} else {
wait(60_000);
}
}
public synchronized wakeMeUpInside() {
notify();
}
}
What I dislike is having to enter the monitor only for waking something up, which means that the notifying thread may be delayed for no good reason. As the choices of native synchronization are limited, I thought I'd switch to Condition, but it has exactly the same problem:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called.
Here's a semaphore based solution:
class Worker {
// If 0 there's no work available
private workAvailableSem = new Semaphore(0);
public void run() {
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
// Try to obtain a permit waiting up to 60 seconds to get one
boolean hasWork = workAvailableSem.tryAquire(1, TimeUnit.MINUTES);
if (hasWork) {
doIt();
}
}
public wakeMeUpInside() {
workAvailableSem.release(1);
}
}
I'm not 100% sure this meets your needs. A few things to note:
This will add one permit each time wakeMeUpInside is called. Thus if two threads wake up the Worker it will run doIt twice without blocking. You can extend the example to avoid that.
This waits 60 seconds for work to do. If none is available it'll end up back in the run method which will send it immediately back to the step method which will just wait again. I did this because I'm assuming you had some reason why you wanted to run every 60 seconds even if there's no work. If that's not the case just call aquire and you'll wait indefinitely for work.
As per comments below the OP wants to run only once. While you could call drainPermits in that case a cleaner solution is just to use a LockSupport like so:
class Worker {
// We need a reference to the thread to wake it
private Thread workerThread = null;
// Is there work available
AtomicBoolean workAvailable = new AtomicBoolean(false);
public void run() {
workerThread = Thread.currentThread();
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
// Wait until work is available or 60 seconds have passed
ThreadSupport.parkNanos(TimeUnit.MINUTES.toNanos(1));
if (workAvailable.getAndSet(false)) {
doIt();
}
}
public wakeMeUpInside() {
// NOTE: potential race here depending on desired semantics.
// For example, if doIt() will do all work we don't want to
// set workAvailable to true if the doIt loop is running.
// There are ways to work around this but the desired
// semantics need to be specified.
workAvailable.set(true);
ThreadSupport.unpark(workerThread);
}
}
Related
All answers are about how to stop loop of some thread, but what if I don't have a loop but I still want to stop a thread before it executes/processes all lines?
For example I have a thread which usually runs for 7-10 seconds and then dies (terminates):
mThread = new Thread(new Runnable() {
#Override
public void run() {
// some code here
// some here
// some here
// some here
// some here
// all lines takes about 7-10 seconds
}
});
If I started a thread and after 2 or 3 seconds I need to stop it, then how to do it and don't wait 10 seconds?
If your thread is not blocked, and is actually processing stuff, then interrupting it might not help. You can code the thread to check for the interrupt flag on the current thread and then stop if it sees that the flag has been set.
This is how you check to see if the current thread has been interrupted.
Thread.currentThread().isInterrupted();
So you would have to code your thread like this...
mThread = new Thread(new Runnable() {
#Override
public void run() {
// some code here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
// all lines takes about 7-10 seconds
}
});
Then you can go ahead and interrupt the mThread and it will have an effect. Though it will still continue processing the current some here step it is on.
Explanation
The preferred way is to implement a stopping mechanism in the thread. You can also try to observe the interrupt flag. You can interrupt from outside using the Thread#interrupt method and the thread can check the flag using Thread#isInterrupted and Thread#interrupted (see documentation of Thread).
There is no way to force a thread from outside to stop without the thread actually implementing the logic by itself. There is the Thread#stop method but it is deprecated and should never be used. From its documentation:
Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many 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. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
Solution
You could modify the thread like this:
public class MyThread implements Runnable {
private volatile boolean mShouldStop = false;
public void shutdown() {
mShouldStop = true;
}
#Override
public void run() {
// First line ...
if (mShouldStop) return;
// Second line ...
if (mShouldStop) return;
// Third line ...
if (mShouldStop) return;
}
}
So you need to periodically check the flag and then manually abort.
Usually such threads have some kind of while (true) loop. In this case it gets easier, you could do:
#Override
public void run() {
while (!mShouldStop) {
// Do something ...
}
}
Depending on your application you might interpret the interruption flag as signal for a thread shutdown. Then your code could look like
#Override
public void run() {
while (!Thread.interrupted()) {
// Do something ...
}
}
Note
The mShouldStop needs to be volatile to ensure it is updated correctly for the Thread. See the tutorial by Oracle for Atomic Access.
You interrupt the thread with mThread.interrupt(). But, for this to work, your thread needs to check the interrupt status (by sleeping). Check out this thread.
For more details, refer this thread.
You need to check the interrupt status in your thread. Something like this
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class ThreadInterruptor {
private static class Worker implements Runnable {
#Override
public void run() {
while (true) {
IntStream.range(0, Short.MAX_VALUE).forEach(i ->noop());
if (Thread.currentThread().isInterrupted()) {
System.out.println("i got interrupted");
break;
}
}
}
private void noop(){}
}
public static void main(String[] args) throws Exception{
Thread thread = new Thread(new Worker());
thread.start();
TimeUnit.SECONDS.sleep(5);
thread.interrupt();
}
}
My application has 1 global driver, which is responsible for doing the low-level work.
I then have 2 threads, both of which use infinite loops to get some work done. My question is how to allow 1 thread to use the driver as much as possible, but giving a chance to the second thread to use it when necessary.
To elaborate, the code I have is as follows:
public class Game {
private static final Object LOCK = new Object();
private static final Logger LOGGER = Logger.getLogger(Game.class);
private WebDriverController controller;
public Game(WebDriverController controler) {
this.controller = controller;
}
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
}
}
}).start();
}
public void startThreadB() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
...
...
synchronized (LOCK) {
controller.doSomethingB();
}
...
...
}
}
}).start();
}
}
The logic is to allow the first thread to execute doSomethingA() as much as possible, with the second thread only acquiring the lock to complete little tasks and then giving the lock back to the first thread.
Using this code, the first thread will continuously use the controller to do what it needs to do, whereas the second thread gets stuck waiting at its synchronized block. The way I have currently fixed this is by adding a pause to the first thread, to give the second thread a chance to acquire the lock, as follows:
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
LOGGER.error(null, e);
}
}
}
}).start();
}
This does work exactly as intended, but it doesn't seem right. I'm not happy with the manual pause after each iteration, especially if the second thread does not need the lock as it's wasting time.
What do I replace the pause with to make this more efficient?
Why you use synchronized in run()? Use synchronized or Lock in your methods in WebDriverController.
public void doSomeThingA(){
lock.lock();
try {
//your stuff
} finally {
lock.unlock();
}
}
And in run method of Thread invoke these methods.
I think you are approaching this from the wrong direction, as in your current setup 99.999% of the time thread A calls for a monitor the processing time is wasted. However as I do not have enough details about your actual problem, here is a quick solution using a ReentrantLock with fair scheduling (FIFO):
protected final ReentrantLock lock = new ReentrantLock(true); // fair scheduling
public void functionA() {
lock.lock();
try {
controller.functionA();
} finally {
lock.unlock();
}
}
public void functionB() {
lock.lock();
try {
controller.functionB();
} finally {
lock.unlock();
}
}
Explanation:
If Thread A is currently holding the lock and Thread B calls, B is guaranteed to receive the monitor right after A releases it, even if A immediately (before any thread switch occurs) calls for it again.
There are a few options here. The best bet in this instance is likely to be remove the responsibility of deciding when to do work from the threads and instead, waiting for an event from a monitor to release the threads to do work. You can then schedule the work in whichever ratio is best suited to the purpose.
Alternatively, remove the lack of thread safety from your controller code.
Assuming that above thread organization is the best way to go for your particular case, your problem is that first thread holds the lock too long, thus starving the second one.
You can check if doSomethingA function really needs locked driver all the time while it is being executed (in most cases it doesn't), and if not split it into multiple smaller execution blocks, some of which hold the lock while other's don't. This will create more time for second thread to kick in when it needs to.
If that cannot be done then you really need to rethink your app, because you have created a resource bottleneck.
It looks like Thread.yield () is what you are looking for.
I want to create a thread to make some HTTP requests every few seconds and is easy to pause and resume at a moments notice.
Is the way below preferred, safe and efficient?
public class Facebook extends Thread {
public boolean running = false;
public void startThread() {
running = true;
}
public void stopThread() {
running = false;
}
public void run() {
while(true) {
while(running) {
//HTTP Calls
Facebook.sleep(2000);
}
}
}
}
Your Code:
In your example, the boolean should be volatile boolean to operate properly. The other issue is if running == false your thread just burns CPU in a tight loop, and you probably would want to use object monitors or a Condition to actually wait idly for the flag to become true again.
Timer Option:
I would suggest simply creating a Timer for this. Each Timer implicitly gets its own thread, which is what you are trying to accomplish.
Then create a TimerTask (FacebookTask below is this) that performs your task and from your main control class, no explicit threads necessary, something like:
Timer t;
void resumeRequests () {
if (t == null) { // otherwise its already running
t = new Timer();
t.scheduleAtFixedRate(new FacebookTask(), 0, 2000);
}
}
void pauseRequests () {
if (t != null) { // otherwise its not running
t.cancel();
t = null;
}
}
Note that above, resumeRequests() will cause a request to happen immediately upon resume (as specified by the 0 delay parameter); you could theoretically increase the request rate if you paused and resumed repeatedly in less than 2000ms. This doesn't seem like it will be an issue to you; but an alternative implementation is to keep the timer running constantly, and have a volatile bool flag in the FacebookTask that you can set to enable/disable it (so if it's e.g. false it doesn't make the request, but continues checking every 2000ms). Pick whichever makes the most sense for you.
Other Options:
You could also use a scheduled executor service as fge mentions in comments. It has more features than a timer and is equally easy to use; they'll also scale well if you need to add more tasks in the future.
In any case there's no real reason to bother with Threads directly here; there are plenty of great tools in the JDK for this job.
The suggestion to using a Timer would work better. If you want to do the threading manually, though, then something more like this would be safer and better:
class Facebook implements Runnable {
private final Object monitor = new Object();
public boolean running = false;
public void startThread() {
synchronized (monitor) {
running = true;
monitor.notifyAll();
}
}
public void stopThread() {
synchronized (monitor) {
running = false;
}
}
#Override
public void run() {
while(true) {
try {
synchronized (monitor) {
// Wait until somebody calls startThread()
while (!running) {
monitor.wait();
}
}
//HTTP Calls
Thread.sleep(2000);
} catch (InterruptedException ie) {
break;
}
}
}
}
Note in particular:
You should generally implement Runnable instead of subclassing Thread, then use that Runnable to specify the work for a generic Thread. The work a thread performs is not the same thing as the thread itself, so this yields a better model. It's also more flexible if you want to be able to perform the same work by other means (e.g. a Timer).
You need to use some form of synchronization whenever you want two threads to exchange data (such as the state of the running instance variable). There are classes, AtomicBoolean for example, that have such synchronization built in, but sometimes there are advantages to synchronizing manually.
In the particular case that you want one thread to stop work until another thread instructs it to continue, you generally want to use Object.wait() and a corresponding Object.notify() or Object.notifyAll(), as demonstrated above. The waiting thread consumes zero CPU until it is signaled. Since you need to use manual synchronization with wait/notify anyway, there would be no additional advantage to be gained by using an AtomicBoolean.
Edited to add:
Since apparently there is some confusion about how to use this (or the original version, I guess), here's an example:
class MyClass {
static void main(String[] args) {
FaceBook fb = new FaceBook();
Thread fbThread = new Thread(fb);
fbThread.start();
/* ... do stuff ... */
// Pause the FaceBook thread:
fb.stopThread();
/* ... do more stuff ... */
// Resume the FaceBook thread:
fb.startThread();
// etc.
// When done:
fbThread.interrupt(); // else the program never exits
}
}
I Would recommend you to use a guarded blocks and attach the thread to a timer
Hallo I've been debugging my code for a whole day already, but I just can't see where could be wrong.
I use SerialPortEventListener on a main thread, in a working thread I have a client socket communicating to a server.
Since after this working thread reach return, I still need some wrap up work done in the main thread, i want to create a "pseudothread" that wait in the main thread until the it is notified from the listener onEvent method.
but this pseudothread seems to be waiting forever.
I checked the locked thread pseudoThread, they should have the same object id in the Runnable and in Listener class.
"PseudoThread waiting" got displayed, but PseudoThread awake is never showed.
Console output shows:
PseudoThread waiting
..
..
false notified pseudothread.
PS if I create a lock in Main class with public final Object lock = new Object(); and replace all main.pseudoThread with main.lock, I get java.lang.IllegalMonitorStateException.
private class Pseudo implements Runnable{
Main main;
public Pseudo(Main main) {
this.main = main;
}
#Override
public void run() {
synchronized(main.pseudoThread){
try {
System.out.println("PseudoThread waiting");
main.pseudoThread.wait();
System.out.println("PseudoThread awake");
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
}
in main method:
public static void main(String[] args) {
Main main = new Main();
main.initArduino();
//more code. including starting the working thread
main.pseudoThread = new Thread(main.new Pseudo(main));
main.pseudoThread.start();
try {
main.pseudoThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void initArduino() {
arduino = new Arduino(this);
if(!arduino.initialize())
System.exit(1);
}
and in the listener class (which also runs in main thread)
//class constructor;
public Arduino(Main Main){
this.main = Main;
}
//listening method
public void serialEvent(SerialPortEvent oEvent){
//some code to interract with working thread.
record();
}
private void record(){
synchronized(main.pseudoThread){
main.pseudoThread.notify();
System.out.println("notified pseudothread.");
}
}
Without looking too deeply into what might actually be happening, I can see that your use of wait()/notify() is all wrong. Probably you are experiencing a "lost notification." The notify() function does nothing if there is no thread waiting for it at the moment when it is called. If your serialEvent() function calls notify() before the other thread calls wait(), then the notification will be lost.
Consider this example:
class WaitNotify() {
private final Object lock = new Object();
private long head = 0;
private long tail = 0;
public void consumer() {
synchronized (lock) {
while(head == tail) {
lock.wait();
}
doSomething();
count head += 1;
}
}
public void producer() {
synchronized (lock) {
tail += 1;
lock.notify();
}
}
}
The essential points are:
(1) The consumer() function waits for some relationship between data to become true: Here, it waits for head != tail.
(2) The consumer() function waits in a loop. There's two reasons for that: (a) Many programs have more than one consumer thread. If consumer A wakes up from the wait(), there's no guarantee that consumer B hasn't already claimed whatever it was that they both were waiting for. And (b) The Java language spec allows foo.wait() to sometimes return even when foo.notify() has not been called. That's known as a "spurious wakeup." Allowing spurious wakeups (so long as they don't happen too often) makes it easier to implement a JVM.
(3) The lock object is the same lock that is used by the program to protect the variables upon which the condition depends. If this example was part of a larger program, you would see synchronized(lock) surrounding every use of head and tail regardless of whether the synchronized code is wait()ing or notify()ing.
If your own code obeys all three of the above rules when calling wait() and notify(), then your program will be far more likely to behave the way you expect it to behave.
As suggested by james it could be lost notification case or it could be that.. Two Threads 1- Your Main Thread and 2- Pseudo thread Are waiting on the same Thread Instance Lock (main.pseudoThread)( Main thread waits on the same lock by calling join method).
Now you are using notify which wakes the Main thread from join method and not the one
waiting in your Pseudo. To check for the second case try calling notifyall in record this will either
confirm the second case or will rule this possibility.
Anyways please refactor your code not to use synch on Thread instance its bad practice. Go for ReentrantLock or CoundDownLatch something.
Usage of notify and wait seem to be incorrect. Method name notify can be a bit misleading because it is not for general purpose "notifying". These methods are used to control the execution of synchronization blocks. Wait will allow some other thread to synchronize with same object while current threads pauses. Basically this is used when some resource is not available and execution can not continue. On the other hand notify will wake one waiting thread wake from wait after notifying thread has completed its synchronized-block. Only one thread can be in synchronized block of the same object at the same time.
If the idea is just keep the main program running until notified then semaphore would be much more appropriate. Something like this.
public void run() {
System.out.println("PseudoThread waiting");
main.semaphore.acquireUninterruptibly();
System.out.println("PseudoThread awake");
}
//...
private void record(){
main.semaphore.release();
}
//...
public static void main(String[] args) {
main.semaphore = new Semaphore(0);
//...
}
I have a method called action() that deploys three threads. Each deployed thread or worker thread falls into a while loop based on a single instance variable of type boolean being true, for example boolean doWork = true, each thread will have a while(doWork){} loop.
When a thread finishes the job will set the doWork to false stopping all the threads from looping. Then I would like to be able to somehow let the main thread recall the action() method to redeploy the threads to do another job. (If I use one of the worker threads to call the action() method is it OK ?) will the worker thread terminate once it calls the action() method and somehow die ?
I limited the example to two threads for simplicity
Thanks
class TestThreads{
boolean doWork = true;
void action(){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
}
//innerclasses
class ThreadOne implements Runnable{
Thread trd1;
public ThreadOne(){//constructor
if(trd1 == null){
trd1 = new Thread(this);
trd1.start();
}
}
#Override
public void run(){
while(doWork){
//random condition
//would set doWork = false;
//stop all other threads
}
action();//is the method in the main class
}
}
class ThreadTwo implements Runnable{
Thread trd2;
public ThreadTwo(){//constroctor
if(trd2 == null){
trd2 = new Thread(this);
trd2.start();
}
}
#Override
public void run(){
while(doWork){
//random condition
//would set doWork = false;
//stop all other threads
}
action();//is the method in the main class
}
}
}
How about this implementation:
Declare a class member doWork, a counter for currently active threads and a synchronization object:
private volatile boolean doWork = true;
private AtomicInteger activeThreads;
private Object locker = new Object();
In main:
while(true) {
// call action to start N threads
activeThreads = new AtomicInteger(N);
action(N);
// barrier to wait for threads to finish
synchronized(locker) {
while(activeThreads.get() > 0) {
locker.wait();
}
}
}
In thread body:
public void run() {
while(doWork) {
...
// if task finished set doWork to false
}
// signal main thread that I've finished
synchronized(locker) {
activeThreads.getAndDecrement();
locker.notify();
}
}
Skeleton code
// OP said 3 threads...
ExecutorService xs = Executors.newFixedThreadPool(3);
...
// repeat the following as many times as you want...
// this is the setup for his 3 threads - as Callables.
ArrayList<Callable<T>> my3Callables = new ArrayList<Callable<T>>();
my3Callables.add(callable1);
my3Callables.add(callable2);
my3Callables.add(callable3);
try {
List<Future<T>> futures = xs.invokeAll(my3Callables );
// below code may not be needed but is useful for catching any exceptions
for (Future<T> future : futures) {
T t = future.get();
// do something with T if wanted
}
}
catch (ExecutionException ee) {
// do something
}
catch (CancellationException ce) {
// do something
}
catch (InterruptedException ie) {
// do something
}
I'll expand my comment (even though #babernathy as added this to his answer).
Typically where you have a pool of threads where you want to execute some piece of work, and you have a main thread managing the items of work that you want done, the ExecutorService provides the ideal framework.
In your main object, you can create an instance of the service (with the number of threads you want), and then as you generate a piece of work, submit it to the service, and the service will pick the next available thread from the pool and execute it.
If you have a dependency on knowing if particular pieces of work have completed, you can use something like a CountDownLatch to track when threads have completed their work. My point, there are quite a few existing frameworks for this kind of activity, no need to go through the pain all over again...
It's a little difficult to give you an exact solution without any code. It sounds like you are describing the producer/consumer pattern where you give a set of worker threads some tasks and when they are done, you give them more.
Here is a web page that does an OK job of describing what to do.
Also take a look at the ExecutorService that allows you to submit Runnables and have them executed.
A simple solution is to have the main thread sleep:
static boolean doWork = true; // better to use AtomicBoolean
void action() {
// start workers, which eventually set doWork = false
while (doWork) {
Thread.sleep(/**time in millis**/); // main thread waits for workers
}
// logic to run action() again, etc.
}
The main thread starts the workers, periodically waking up to check if they've terminated. Since the main thread is an "arbiter", it probably shouldn't die just to be resurrected by one of its children.
Reference
Thread.sleep()
AtomicBoolean