How to access variables in a runnable object in Java - java

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.

Related

Can I synchronize reads of control variables?

The following code will work, but I slightly resent having to write the isRunning() method:
class Test {
private boolean running;
public void startX() {
synchronized(this) {
running = true
}
while (isRunning()) {
//do something
}
}
public synchronized void stopX() {
running = false;
}
private synchronized boolean isRunning() {
return running;
}
}
Can I synchronize reads of the running variable in the while (running){} in some other way, or do I have to write the isRunning() method? The same question applies to other control variables as well, eg
for (;running;) {}
or
if (running) {}
In all of these cases it seems as though you're forced into writing a pointless method to get the synchronization correct. Am I missing something?
if you are only resetting the value of running once to designate to stop, you might be able to use the volatile keyword.
However, if you need to start and stop many times, this won't work. This is because volatile fields "may miss an update"
Here's a link to explanation of when volatile works in cases like this link
here's the code sample from that link incase it goes dead:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
If you need to start and stop many times, then you need to either use one of the Java 5 concurrent lock objects or explicit synchronization
You could make the running field volatile. Making the field volatile puts the JVM on notice that it should make changes to that field visible to other threads.
The "miss an update" caveat is for cases where you want to read a value and update based on that value, which doesn't seem applicable here.
Multiple threads can write to this field, if all they're doing is setting a boolean flag then this won't be a problem.
Alternatively, if you are trying to cancel a thread, there's already an equivalent flag provided on Thread for this (and the visibility issue is taken care of). You can call interrupt on a thread, the code in the Runnable can query Thread.currentThread().isInterrupted() in order to tell whether it's been interrupted. This is preferable over using your own flag because the interruption will cause the thread to wake up if it is waiting or sleeping. With your own flag you have to wait until control reaches a place where the flag can be tested.
just to add up to other people's answer that suggested volatile .
Alternatively you could create a class for the checks.
I have made the variable to be static, so all threads will be pointing to same object.
class Runner{
boolean static running=true;
public static synchronized boolean getRunning(){
return running;
}
public static synchronized boolean setRunning(boolean r){
running=r;
}
}
NOTE:
if you don't require the global variable, then remove the static

Thread switch/case ignoring statement

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 .

Threads: Busy Waiting - Empty While-Loop [duplicate]

This question already has answers here:
Is this starvation?
(2 answers)
Closed 9 years ago.
During our lessons in the university, we learned about Threads and used the "Busy Waiting" method for an example of a Car waiting at a TrafficLight. For this task we build three classes:
TrafficLight (implements Runnable)
Car (implements Runnable)
Main
In our Main class we start two Threads, one of Car, and one of TrafficLight. The Car has the boolean attribute hasToWait. The run() method in this class works the way, that it works through a while loop as long as hasToWait == true. To change this, we have the notifyCar() method in the Car class, which is used by the TrafficLight. The run() method in TrafficLight runs through a Thread.sleep() to simulate a certain time of waiting.
Everything works fine at my Prof's but eventually I have serious problems with it. As long as the while loop in the Car class is empty. When I put in a System.out.println() - which is not empty, it works. But if the Syso is empty, the result is no displaying of the Text of the Run method.
Also it's working when the Thread.sleep() in TrafficLight is 0. Than it works with an empty while loop.
Here is my code:
Car.java:
package trafficlight;
public class Car implements Runnable {
private boolean hasToWait = true;
public void run() {
this.crossTrafficLight();
}
public void crossTrafficLight() {
while(hasToWait){ for(int i = 0; i<20; i++){System.out.println("123");}} // Busy waiting
System.out.println("Auto fährt über Ampel");
}
public void notifyCar() {
this.hasToWait = false;
System.out.println("Test");
}
}
TrafficLight.java:
package trafficlight;
public class TrafficLight implements Runnable {
private Car car;
public TrafficLight(Car car) {
this.car = car;
}
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.car.notifyCar();
}
}
Main.java:
package trafficlight;
public class Main {
public static void main(String[] args){
Car car = new Car();
TrafficLight tl = new TrafficLight(car);
new Thread(car).start();
new Thread(tl).start();
}
}
Where is the problem? Why does it work at my profs but not at my computer? I got the code 1:1 in my Eclipse Juno, using JRE 1.7
In addition to everything said in this other answer (just substitute your hasToWait for finished in that answer), the reason why the code starts working when you add a println is as follows:
println is a synchronized method;
you call it in both threads;
this creates a happens-before relationship between the two threads;
therefore the write to the boolean flag becomes visible to the child thread.
You could say that it starts working mostly by accident: you are piggybacking on the synchronization going on in println.
The real problem with your code is the instance field hasToWait. This field is being used by two threads. The car thread reads the value, and the traffic light thread updates the value after some time.
The access to this field must be synchronized in some way.
There are two ways to do this:
Use the synchronized keyword. Either by using a synchronized block at all places, where it is read or written, or - better - write a synchronized getter and a synchronized setter, then use the getter and the setter inside the Car class.
Use the volatile keyword. Just declare your field as volatile. This keyword exists for exactly that case. More information on volatile can be found in Oracle's Java Tutorials.
After reading the article about atomic access (see link above), it should be clear that option 2 (declaring volatile) is the far better option - for this use case.
Now to the difference you see between your computer and your professor's computer: As long as you are using a single-core-processor, you will see updates on an instance field in other threads as though they were synchronized, because the CPU does not have to synchronize these values in the other cores' cache areas. If you use a multi-core-processor, then the JVM is able to run threads on several cores. That means, that these cores have to synchronize values, and the volatile mechanism is exactly designed for that.

Thread stops itself

I've been searching for a solution for a long time, but I wasn't able to find one, so I'll ask my question here.
I have a thread which is started when the program starts and supposed to be idle until it is enabled by the application. Simple code example:
private class UpdaterThread extends Thread {
private static final int UPDATE_RATE = 50;
private Timer updateTimer = new Timer();
private boolean enabled;
public void run() {
while (!closeRequested) {
// If this is uncommented, the thread works as it's supposed to.
// System.out.print("");
if (enabled) {
Snapshot next = getNextSnapshot(1f / UPDATE_RATE);
System.out.println("Got next Snapshot");
updateTimer.sync(UPDATE_RATE);
System.out.println("Push");
currentSnapshot = next;
}
}
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
}
When you read a variable, which the JIT believes you didn't modify, it inlines the value. If you then modify the value later, it is too late, the value has been embedded in the code.
A simple way to avoid this is to use volatile but you would still have the problem than the thread is busy waiting for the value to change and there doesn't appear to be a good reason to do this. Another option is to add code which confuses the JIT do it doesn't do this optimisation. An empty synchronized block is enough but a friendlier way is to use Thread.sleep() which at least doesn't use up all your CPU.
I suggest using a volatile fields and sleeping with a period of 10-100 ms. However a simpler option is to not start the thread until it is needed.
since run() is called when the thread is started, you could just wait until later in the program to start it, also threads do not extend "Thread" but implements "Runnable" so the class definition would look like:
public class UpdaterThread implements Runnable
hope it helps :D

How to Thread a complex Model class to provide synchronization with a Controller class?

How can I proceed in a controller based on whether just one part of a complex model has produced the correct flag?
A controller class is playing a queue of Midi sequences while holding onto an instance of a model class that is dynamically updated via user button presses. After the Midi queue ends, the controller needs to synchronize with the model to check that the user has made a certain number of entries before proceeding to update the interface and move to the next part of the application. The Model represents quite a lot of other data in addition to the ArrayList of user button presses, so the challenge is how to best compartmentalize the synchronization part.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
//Controller
...
Thread entriesCoordination = new Thread( new Model.InnerClass);
entriesCoordination.start();
Thread t = new Thread (this);
t.run();
...
//in runnable nested class in controller
private Model.InncerClass c = new Model.InnerClass();
public void run() {
synchronized( c) {
while (!c.hasFinishedEntries()){
try{
c.wait();
} catch (InterruptedException ignore{}
}
}
}
//Midiqueue completed and Entries finished
}
//in Model
//in runnable nested class in Model
public synchronized boolean hasFinishedEntries() {
return fIsFinishedWithEntries;
}
public void run() {
while(true) {
try{
synchronized(this) {
try{
if(entriesArray.size() == max_size) {
fIsFinishedWithEntries = true;
notifyAll();
} else {...}
}
}
}
}
}
Furthermore, this seems wasteful because it basically means that I need to create a thread and run the inner class of the Model in parallel the entire duration of the time that the user can make these button selections, rather than something that would just poll the Model when I know that the Midi queue has ended.
What's the design pattern to synchronize to one flag in a Model class from a Controller class without having to make a inner class in the model just to handle the synchronization.
I think the right thing to do here is to use an AtomicBoolean and define methods on each of your thread objects to get and set the boolean.
The Model.InnerClass would be changed to add the AtomicBoolean and to change the getter to not be synchronized.
private final AtomicBoolean fIsFinishedWithEntries = new AtomicBoolean();
public boolean hasFinishedEntries() {
return fIsFinishedWithEntries.get();
}
In the run method it something needs to set the finished boolean to be true.
public void run() {
while(true) {
if (entriesArray.size() == max_size) {
synchronized (this) {
fIsFinishedWithEntries.set(true);
notifyAll();
}
} else {...}
}
}
}
You'll need to rest it to false somewhere if you are doing this more than once.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
You need to first create your Model.InnerClass instance and inject that into your controller thread. Making the hasFinishedEntries() be static is ugly so instead in your controller you'd call:
private Model.InnerClass innerClass;
public ControllerThread(Model.InnerClass innerClass) {
this.innerClass = innerClass;
}
...
public void run() {
synchronized (innerClass) {
while (!innerClass.hasFinishedEntries()){
innerClass.wait();
}
}
}
How can I access whether the entries are finished without synchronizing on the entire Model class?
You can obviously just poll the hasFinishedEntries() whenever you want to see if the queue has ended. I'm not sure of a better way to do this without a thread. Is there some way to setup a UI event which checks for a condition every so often?

Categories