I'm just testing some concurrent programming in Java.
Basically I have a class (Light) which is a kind of finite state machine, and changing its state regarding the commands.
That's what I'm trying to: The light is in ON state, I send a command to the thread of this class for changing the state in OFF.
But I got a problem during the execution.
First, let me present the class:
enum State {ON, OFF};
public class Light implements Runnable {
private boolean cmdOn;
private boolean cmdOff;
State state;
public Light() {
cmdOn = false;
cmdOff = false;
state = State.ON;
}
#Override
public void run() {
while(true) {
switch(state) {
case ON:
if(cmdOff) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = State.OFF;
}
break;
case OFF:
if(cmdOn) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = State.ON;
}
break;
}
}
}
public void setCmdOn(boolean cmdOn) {
this.cmdOn = cmdOn;
}
public void setCmdOff(boolean cmdOff) {
this.cmdOff = cmdOff;
}
public State getState() {
return state;
}
}
And my main class:
public class Main {
public static void main(String args[]) throws InterruptedException {
Light light = new Light();
Thread t = new Thread(light);
t.start();
printState(light, 500, 1);
light.setCmdOff(true);
printState(light, 500, 4);
}
public static void printState(Light l, int time, int number) throws InterruptedException {
for(int i= 0; i < number; i++) {
System.out.println(l.getState());
Thread.currentThread().sleep(time);
}
}
The output shows me that I'm stuck in the ON state while I should be in OFF state.
In a second run, after putting an instruction (System.out.println or whatever...) above the if statement which verify that cmdOff is true, it's magically works.
I don't understand why the cmdOff variable is not pass to true during the first run !?
And why in the second run it works?
I miss something, probably a synchronizing block. But I don't find the explanation to deal with this.
Thanks.
Best regards,
You should read about synchronization. Without synchronization you risk getting visibility errors where one thread can't see changes another thread made to a variable shared between the threads.
Tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
You can use a synchronized block that uses an object both threads know about to do locking. If both threads always synchronize on that known object when reading or updating your shared data, then visibility and atomicity will never be an issue.
Read here to fully understand "synchronized": http://tutorials.jenkov.com/java-concurrency/synchronized.html
You should also be able to just declare the shared variable as volatile. This means all writes and reads on it create a happens-before relationship with other threads, which is what you want. Read the tutorial above to fully understand the issues and terminology.
Read here to fully understand "volatile": http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html.
Try using volatile on cmdOn and cmdOff:
private volatile boolean cmdOn;
private volatile boolean cmdOff;
Volatile variable explanation in Java docs
Without it (or synchronization) changes may not be visible.
Without any synchronization, there are no guarantees that the running thread will ever see the values written to cmdOff and cmdOn by the other thread. Also, lack of synchronization on state means any changes by the running thread may not be seen by the other thread. Try making cmdOn, cmdOff and state volatile .
Related
Why do primitive variable in multithreading little program, behave as a volatile variable? Please help me in my code.
/**
* Practice with threads problem visibility.
* #author Matevosyan Vardan
* #version 1.0
* created on 21.09.2017
*/
public class VisibilityProblem {
private static int countingVal = 0;
public static int getCountingVal() {
return countingVal;
}
Start in main
public static void main(String[] args) throws InterruptedException {
Thread looperR = new VisibilityProblem.Looper();
Thread listener = new VisibilityProblem.Listener();
listener.start();
looperR.start();
listener.join();
looperR.join();
}
Class to wright and increase counting variable after sleep 500 millisecond
to wait a little, what helps do some staff Listener thread.
public static class Looper extends Thread {
#Override
public void run() {
while (VisibilityProblem.countingVal < 5) {
VisibilityProblem.countingVal++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("increase " + VisibilityProblem.countingVal);
}
}
}
Class to read and assign counting value
public static class Listener extends Thread {
#Override
public void run() {
int localCount = VisibilityProblem.countingVal;
while (localCount < 5) {
if (localCount != VisibilityProblem.countingVal) {
System.out.println("It is " + localCount + " now");
localCount = VisibilityProblem.countingVal;
}
}
}
}
}
Why do primitive variable in multithreading little program, behave as a volatile variable
It depends what you mean by behave as a volatile variable.
If you mean, why are changes made by one thread seen in the second thread ... then the reason is that the JLS allows this.
If you mean, why are changes made by by one thread guaranteed to be seen in the second thread ... then your program does not provide evidence1 of this!!
The difference in visibility semantics between ordinary and volatile variables are:
For a volatile, the changes are guaranteed to be immediately visible.
For an ordinary variable, the changes may be visible immediately, or with a delay, or ... never. Any of those behaviors conforms with the Java Memory Model.
Seeing the changes with ordinary variables when you run the program on one hardware platform with one version of the Java compiler on a computer running with one set of applications running, etc, etc does not mean that you will always see that in all circumstances.
1 - Indeed, it is theoretically impossible to write a program that can do this. But your program could provide evidence that this is not guaranteed ... or that a (hypothetical) guarantee is not being met.
This code end up with different results if I change the parameter of sleep(), and here is some sample outcomes:
1.sleep(1l), the thread will always terminate automaticlly, the "Stoped" statement will always be printed, and the icon of "Terminate" in Eclipse will be grey too. (seems working perfectly huh?)
2.sleep(1000l), here comes the problem, if main thread sleeps for 1 second, the Thread v will never terminated automaticlly, the "Stoped" will not be printed, and the icon of "Terminate" is red, which means there is still some thread running.
I know it could be solved if I add "volitale" for the parameter "isRunning", but I wonder why and how does the sleep() statement affect the outcome?
PS:I'm a newbie for both java and english, so I apologize for any possible discomforts due to this question.
public class VolitaleTest {
public static void main(String[] args) throws InterruptedException {
Vo v = new Vo();
new Thread(v).start();
Thread.sleep(1000l);
v.setRunning(false);
System.out.println(v.i);
}
}
class Vo implements Runnable {
private boolean isRunning = true;
int i = 0;
public void run() {
while (isRunning) {
i++;
// System.out.println("Running");
/*
* Once you add this statement, you will always be able to terminate
* the program automatically, no matter how long the thread sleeps.
*/
}
System.out.println("Stoped.");
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
}
volatile makes it possible for what one thread wrote up to and including writing to the volatile variable to be visible to another thread starting from when it reads that variable. If the variable is not volatile then that happens-before memory relationship is not guaranteed.
I am creating a mutli threaded application, and I have a question regarding the use of synchronized methods.
Lets say I have the following component which would be accessed by multiple threads.
Component.java
public class Component {
private boolean active;
//Constructor
public Component(){
active = false;
}
synchronized public void initiate(){
//do something
active = true;
}
synchronized public void closedown(){
//do something
active = false;
}
public void doSomething(){
//do something
}
public boolean isActive(){
return active;
}
}
If I have two threads accessing the the same Component object and the first thread gets halted in the Component.closedown() before it has set active = false, and the second thread picks up and calls Component.isActive(), will the second thread block until the first thread has finished the closedown, or will it get the returned value of true?
If it is the latter, how can I make this thread safe?
Yes, that is the essence of mutual-exclusion locks (mutexes). If a thread gets descheduled by the OS while holding a mutex, all other threads requiring the mutex to proceed will be stalled.
The above is actually the reason why, even if we take care to make all our critical sections very short and fast to execute, mutexes will still cause occasional latency spikes, and the spikes will be huge in proportion to regular latency. For example, your simple getter will execute in a couple of nanoseconds when uncontended, but may take 10µs or more if the thread holding the mutex is descheduled at an inconvenient time.
NOTE: The code in your question lacks the synchronized designation on isActive, but I assume your question is about what would happen if it was synchronized—because the code has a data race without it. Specifically:
will the second thread block until the first thread has finished the closedown, or will it get the returned value of true?
Without synchronized it will do neither: it won't block, but it won't be guaranteed to ever return the true value. You are only guaranteed to observe the initial value (that's what the data race is about).
If you are looking for a practical advice to improve your code, then don't synchronize isActive method, but make the active flag volatile. This is standard practice for your use case.
You need to have use a lock to protect the critical sections. As some methods read from the value and some write to the value, you can try using a ReadWriteLock.
public class Component {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private boolean active;
//Constructor
public Component(){
active = false;
}
public void initiate(){
// non-critical section
rwl.writeLock().lock();
try {
// critical section
active = true;
} finally {
rwl.writeLock().unlock();
}
}
public void closedown(){
// non-critical section
rwl.writeLock().lock();
try {
// critical section
active = false;
} finally {
rwl.writeLock().unlock();
}
}
public void doSomething(){
// do something
}
public boolean isActive(){
rwl.readLock().lock();
boolean status = active;
rwl.readLock().unlock();
return status;
}
}
I was going through an "JAX London 2011" presentation on "Modern Java Concurrency". Between the time duration 43:20 - 43:40, a person from the audience says the shutdown variable in the code below should have been declared as volatile and the presenters agree with it (and say that it was pointed out earlier as well, but they just didnt get to modify the presentation). The code in question is:
public abstract class QueueReaderTask implements Runnable {
private boolean shutdown = false;
protected BlockingQueue<WorkUnit<String>> lbq;
public void run() {
while (!shutdown) {
try {
WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
if (wu != null) { doAction(wu.getWork()); }
} catch (InterruptedException e) {
shutdown = true;
}
}
}
public abstract void doAction(String msg);
public void setQueue(BlockingQueue<WorkUnit<String>> q) { lbq = q; }
}
My Question:
I dont think that shutdown should be declared volatile.
My reasoning is that shutdown being a member of a Runnable, each task/thread will have a distinct private copy of that variable. So, why make it volatile?
But since this was discussed in JAX 2011, I am assuming there were lots of expert Java developers in that audience. I dont think all of them would have missed this !
So, what am I missing ?
P.S:-
I can understand that a variable should be declared volatile if it was (potentially) shared by multiple threads, as in the Double-Checked-Locking pattern :
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
each task/thread will have a distinct private copy of that variable. So, why make it 'volatile' ?
You are correct if the shutdown boolean is only modified from within the QueueReaderTask instance. In that case shutdown is only being modified by the one thread and doesn't need to be volatile.
Frankly, the code looks strange to me. Why catch InterruptedException, set the shutdown boolean, and then loop around and exit. Why now just do the following? Why have the shutdown flag at all?
while (true) {
try {
WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
if (wu != null) { doAction(wu.getWork()); }
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
Maybe there is extra code that was removed in the post? If not, I wonder if this was copy and pasted from a larger section of code where shutdown was set to true also in a method call.
P.S:- I can understand that a variable should be declared 'volatile' if it was (potentially) shared by multiple threads, as in the Double-Checked-Locking pattern :
Right. A typical pattern is that shutdown is modified from another thread which is telling the thread to stop processing. In that case it needs to be volatile.
I am going to simulate a traffic light system.
I created the Road Class which extends JFrame and implements Runnable.
Inside the run() method I added the logic to increase the Y Position of each car and It is now simulating the movements of cars.
But now I need to check the status of the Traffic Light, before move a car.
This is my TrafficLight class,
import java.util.Random;
public class TrafficLight implements Runnable {
volatile boolean stop;
public TrafficLight(boolean stop) {
this.stop = stop;
}
#Override
public void run() {
Random randomGenerator = new Random();
while (true) {
if (stop) {
stop = false; //change current status
} else {
stop = true; //change current status
}
try {
Thread.sleep(2000 + randomGenerator.nextInt(2000));
} catch (Exception ex) {
System.out.println("error");
}
}
}
}
Is there any way to check this volatile variable stop, from my Road Class.
If not please suggest me another solution to do this.
Thanks.
Implement an accessor for stop.
public class TrafficLight implements Runnable {
volatile boolean stop;
// Irrelevant code
public boolean isStop() {
return stop;
}
}
Receive the TrafficLight on the Road class constructor and use it to get access to the stop variable
public class Road implements Runnable {
private TrafficLight trafficLight;
public Road (TrafficLight trafficLight) {
this.trafficLight = trafficLight;
}
#Override
public void run() {
// Irrelevant code
if(trafficLight.isStop()) {
// do something
}
}
}
Road (or whoever needs the value) should have access to an instance of TrafficLight and ask it if its green. You can provide a boolean method.
BUT access to this property (stop) should be guarded. volatile keyword doesn't help very much (see below).
I should do something like:
private synchronized void toogleStopped() { // guarded
this.stop = !this.stop;
}
public synchronized boolean isStopped() { // guarded
return this.stop;
}
Events
If some other object needs to react to changes in lights (react to "light has changed" event), use Observer design pattern as #TejasArjun suggested.
Why volatile doesn't help
volatile makes Java avoid assuming variable is not changed "from outside". So if a thread sets its value (or read it before), a second read will use (probably) a cached value (already saved in a CPU register or something). volatile makes Java always read the value from memory.
Said that, the lost update problem remains even with volatile keyword. One thread can 1) read 2) write. Another thread can do the same. And they can do it in this order:
Thread 1 reads false
Thread 2 reads false
Thread 1 sets true (assuming it read false)
Thread 2 sets true (assuming it read false)
And that's not nice :)
So you must tell Java to make read&write atomically. That's why we can use synchronized keyword to make sure a thread does the whole sync'ed block at once, not interlaced with another thread.
Put another way, Does this mean that cars need to listen to traffic light changes?. Observer design pattern may also help here.