There are some good answers here but I thought I'd be more simple.
I want the threads to wake up when an environment variable is set.
In looking at the comments below your question, you say that you are using environmental variables so that two parts of the same program can notify each other. It is also important to note that like @Peter mentions, environmental variable changes that happen outside of an application are not seen by the application.
But in terms of sending a signal from one thread to another, you are using an "environment" variable when you should be using a synchronization primitive. Typically two threads share a lock object. Maybe it needs to be public to be shared or passed into your Runnable
s for the threads to use the same object which is important.
private final AtomicBoolean signal = new AtomicBoolean(false);
One thread calls wait()
on that lock:
while (!signal.get()) {
synchronized (signal) {
signal.wait();
}
}
signal.set(false);
Another thread call notify()
on that lock:
synchronized (signal) {
signal.set(true);
signal.notify();
}
The reason why we use an AtomicBoolean
here is that we have to protect against spurious wakeups. They are rare but under certain thread implementations (or conditions) the wait()
could return without anyone directly calling the notify()
on the object. The AtomicBoolean
allows us to put the wait()
in a while(...)
loop to ensure that the condition has been reached -- this is a good pattern to follow always.
The AtomicBoolean
also allows us to pre-notify. The thread that calls notify()
may do so before the other thread is inside of wait()
in which case the waiting thread may sleep forever. With the AtomicBoolean
this is not the case.