Why volatile is not working properly - java

Today I was creating one timeout job using TimerTask but fell in to a new problem where i have a static volatile boolean variable flag. My understanding is as soon as value of this variable get changed it is notified by all running thread. But when I ran this program I got below output which is not acceptable.
O/P:
--------------
--------------
DD
BB
Exiting process..
CC
My expectation is my last print should be Exiting process.. Why is this strange behavior?
My code is:
public class TimeOutSort {
static volatile boolean flag = false;
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
flag = true;
System.out.println("Exiting process..");
// System.exit(0);
}
}, 10 * 200);
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("BB");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("CC");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("DD");
}
}).start();
}
}
Edit: How can i achieve this ?

volatile pretty much means that each time a thread accesses a variable it must ensure to use the version visible to each thread (i.e. no per-thread caching).
This doesn't force the CC-printing thread to actually get to run immediately after the flag has been set to true. It's entirely possible (especially on a single-core machine) that one thread sets the flag and prints the message before the CC-printing thread even had a chance to run.
Also: note that printing to System.out involves acquiring a lock (somewhere inside the println() call), which can modify the multi-threaded behaviour of test code.

Threads can execute code in any order
thread BB: while (!flag) // as flag is false
thread Main: flag = true;
thread Main: System.out.println("Exiting process..");
thread BB: System.out.println("BB");
My expectation is my last print should be Exiting process..
Threads are designed to run concurrently and independently. It would be surprising if this was always the last statement because you can't be sure where each thread is when you set the flag.

The thread that prints "CC" happened not to receive any CPU time until after your thread that prints "Exiting process..." printed that. This is expected behavior.

It's not volatile not working (if it were not, some of your threads would not have stopped). It's about the order of execution of instructions in the different threads, and this is random (depends on OS scheduling) unless you explicitly synchronize the loops at intermediate steps.

To add an alternative phrasing to the explanations you got: in your sample output, the thread that prints "CC" got suspended (somewhere) "between" the lines while (!flag) and System.out.println(). Which means that after it wakes up, the println() executes before the next check of the flag. (It also won't get woken up just because you change the flag value, but because some other thread blocks or uses up its time slice.)

i didn't test it , but you may achieve it like this
public class TimeOutSort {
static volatile boolean flag = false;
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
synchronized(flag){
flag = true;
notifyAll();
}
}
}, 10 * 200);
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("BB");
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("CC");
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("DD");
}
}
}).start();
}
}

Related

How Java synchronize updates thread value?

I have next code:
boolean signal;
#Test
public void test() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (!signal){
// empty loop body
}
}
});
thread.start();
Thread.sleep(1000);
signal = true;
thread.join();
}
It runs infinity loop due to creation of local copy of signal variable in thread. I know that I can fix it by making my signal variable volatile. But also loop can successfully exit if add synchronized block inside my loop (even empty):
boolean signal;
#Test
public void test() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (!signal){
synchronized (this) {
}
}
}
});
thread.start();
Thread.sleep(1000);
signal = true;
thread.join();
}
How synchronized updates my signal value inside thread?
Synchronized does not updates the signal value itself, it basically just places a couple of flags to avoid two threads use the same object at the same time; something like: MonitorEnter and MonitorExit.
The first one locks the object, and the second one releases.
Take a look at the following article: how-the-java-virtual-machine-performs-thread-synchronization.
Please notice the article is very old; but as far as I understand the logic behind remains.

What is the order of execution of newly created threads in java

class Test {
boolean isFirstThread = true;
private synchronized void printer(int threadNo) {
if(isFirstThread) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFirstThread = false;
System.out.println(threadNo);
}
public void starter() {
new Thread(){
#Override()
public void run() {
printer(0);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(1);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(2);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(3);
}
}.start();
}
}
In the above code, when i call starter from main. I have created four new Threads to call a synchronized function. I know the order of execution of the threads can't be predicted. Unless they all wait for some time, so that first thread can finish and come out of the synchronized block. In which case I expect all threads to be held in a queue so i expected the answer as
0
1
2
3
But consistently(I ran the program more than 20 times) I was getting the output as
0
3
2
1
Which means that the threads are being held in a stack instead of a queue. Why is it so? Every answer in the google result says it is a queue but I am getting it as a stack. I would like to know the reason behind for holding the threads in stack(which is counter intuitive) instead of queue?
The order in which threads start is up to the OS, it is not specified in the Java Language Spec. You call start in the main thread, but when the new thread gets allocated and when it begins processing its Runnable or run method is left to the OS' scheduler to decide.
Be careful not to rely on the order in which threads happen to start.

Execute pairwise threads concurrently

class A
{
public void func()
{
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
}
}
Here, I'm trying the first two threads (say pair A) to run concurrently and the next two threads (say pair B) to run concurrently only after pair A has finished executing.
Also if anybody can explain if it can be achieved via java.util.concurrent or threadgroup. I'll really appreciate any help done.
public void func()
{
Thread a = new Thread()
{
public void run()
{
// statements
}
}
Thread b = new Thread()
{
public void run()
{
// statements
}
}
a.start();
b.start();
a.join(); //Wait for the threads to end();
b.join();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
}
You can use a CountDownLatch to wait until a certain number of threads call countDown(), at which point the main thread can then continue. You will have to make some alterations to your threads -- namely, you'll need to pass them the latch, and you'll need to have them call latch.countDown() when they are done with their jobs so the latch's count will eventually reach 0.
So your main class would look something like:
final CountDownLatch latch = new CountDownLatch(2); // Making this final is important!
// start thread 1
// start thread 2
latch.await(); // Program will block here until countDown() is called twice
// start thread 3
// start thread 4
And your threads would look something like:
new Thread() {
public void run() {
// do work
latch.countDown()
}
}
And only once the first two threads finish will the latch allow the main thread continue and start the other two threads.

How to stop a thread by another thread?

I have some struggle with threads in Java, I have three threads - thread1, thread2, and thread3. Those are doing some task when it started, I want to stop these two threads by thread1. I put thread1 for sleep(500), then I stop the both threads, but the process of two threads are still running. Do you have any idea how to do this?
How're you attempting to stop them? Thread.stop? Be warned that this method is deprecated.
Instead, look into using some sort of flag for thread 1 to communicate to thread 2 and 3 that they should stop. In fact, you could probably use interrupts.
Below, Thread.interrupt is used to implement the coordination.
final Thread subject1 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
final Thread subject2 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final Thread coordinator = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) { }
System.out.println("coordinator stopping!");
subject1.interrupt();
subject2.interrupt();
}
});
subject1.start();
subject2.start();
coordinator.start();
Alternatively, you could also use a volatile boolean (or AtomicBoolean) as means of communicating.
Atomic access provided by volatile and java.util.concurrent.atomic.* allow you to ensure mutation of the flag is seen by the subject threads.
final AtomicBoolean running = new AtomicBoolean(true);
final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {
public void run() {
while (running.get()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
subjects.submit(new Runnable() {
public void run() {
while (running.get()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {
public void run() {
System.out.println("coordinator stopping!");
running.set(false);
subjects.shutdown();
coordinator.shutdown();
}
}, 500, TimeUnit.MILLISECONDS);
Similarly, you could opt to, rather than use AtomicBoolean, use a field such as:
static volatile boolean running = true;
Better yet, if you take advantage of ExecutorServices, you can also program similar code as follows:
final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
subjects.submit(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {
public void run() {
System.out.println("coordinator stopping!");
subjects.shutdownNow();
coordinator.shutdown();
}
}, 500, TimeUnit.MILLISECONDS);
This takes advantage of the fact that ThreadPoolExecutor.shutdownNow interrupts its worker threads in an attempt to signal shutdown.
Running any example, the output should be something to the effect of:
C:\dev\scrap>javac CoordinationTest.java
C:\dev\scrap>java CoordinationTest
coordinator stopping!
subject 1 stopped!
subject 2 stopped!
Note the last two lines can come in either order.
You can't stop a thread from another thread. You can only ask the thread to stop itself, and the best way to do that is to interrupt it. The interrupted thread must collaborate, though, and respond to the interruption as soon as possible by stopping its execution.
This is covered in the Java tutorial about concurrency.
You can either:
Have some boolean flag which the threads check regularly. If it is changed, then, they stop executing (note this can cause race conditions)
Another option would be to use the ExecutorService:
An Executor that provides methods to manage termination and methods
that can produce a Future for tracking progress of one or more
asynchronous tasks.

Java Thread won't stop

I have a JRuby engine which evaluates some scripts and I want to close the thread if it takes more than 5 seconds.
I tried something like this:
class myThread extends Thread{
boolean allDone = false;
public void threadDone() {
allDone = true;
}
public void run() {
while(true) {
engine.eval(myScript);
if(allDone)
return;
}
}
(...)
th1 = new myThread();
th1.start();
try {
Thread.sleep(5000);
if(th1.isAlive())
th1.threadDone();
} catch(InterruptedException e) {}
if(th1.isAlive())
System.out.println("Still alive");
I also tried to kill the thread with th1.stop() or th1.interrupt() but the value retured by th1.isAlive() method is always true.
What can I do?
I want to add that myScript could be "while(1) do; end" and I cannot wait until it's completed. So I want to prevent scripts like that and kill the thread if it takes more than 5 seconds.
Another solution would be to use the built-in mechanism to interrupt threads:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
engine.eval(myScript);
}
}
...
th1 = new myThread();
th1.start();
try {
Thread.sleep(5000);
th1.interrupt();
}
This way, no need for an allDone field, and no risk in failing to synchronize.
To make your Thread stoppable you might want something like.
class MyTask implements Runnable {
public void run() {
try {
engine.eval(myScript);
} catch(ThreadDeath e) {
engine = null; // sudden death.
}
}
}
You can call Thread.stop(), but I suggest you read the warnings on this method first.
If you want a thread to run for up to 5 seconds, the simplest solution is for the thread to stop itself.
class MyTask implements Runnable {
public void run() {
long start = System.currentTimeMillis();
do {
engine.eval(myScript);
} while(System.currentTimeMillis() < start + 5000);
}
}
This assumes you want to run engine.eval() repeatedly. If this is not the case you may have to stop() the thread. It is deprecated for a good reason but it might be your only option.

Categories

Resources