I have a thread:
class Foo extends Thread
{
boolean active = true;
public void run()
{
while(active)
{
//do stuff
}
}
public void end()
{
active = false;
}
public void hibernate()
{
synchronized(this)
{
wait();
}
}
}
If another thread calls end(), will Foo immediately see that active is now false? Specifically, because active isn’t volatile, I’m not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I’m unsure that it will actually do what I intend.
Additionally, if another thread calls hibernate(), which thread will go to sleep? I’m intending Foo to sleep, so if this doesn’t do what I intend, an alternative suggestion would be very welcome.
No it won’t. Or at least, it won’t see it all of the time.
If you want
runto always see the new value immediately, there has to be a “comes after” relationship between the thread assigning to the variable and the thread reading it. This can be achieved:activevolatile,synchronizedblocks around the statements that read and write the variable,AtomicBoolean, orjava.util.concurrent.*packages.Declaring the variable to be volatile is one way of ensuring proper synchronization. It is a fact that proper synchronization imposes a performance overhead. However, proper synchronization is essential for your application to work reliably, and it is NOT “clever” to avoid it.
(Without proper synchronization, your program will probably still work most of the time, and it might even always work on some machines. However, occasionally it won’t work, and the actual behavior is likely to depend on what machine you run the program on, what the machine load is, and other things.)
The thread that makes the call will go to sleep. And it won’t wake up unless some other thread does a
notifyornotifyAllon the same Foo object.If you simply want the application to go to sleep and wake up a bit later, use
Thread.sleep. But beware that usingsleepin the wrong way can make your application slow and unresponsive.