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.
Related
I got an assignment for university where I have to implement a hangman game with Threads in Java.
My problem is that I can't understand how to handle the threads.
In my code there is a GameLeader who prompts the GuessingPlayer to enter a char which he guesses in the startWord. After he did that (run()-method) he takes the message further.
The connection between the two players should be arranged with 'Messages' (own implemented class). It's working if I use run() instead of wait().
Can u help me to understand why the while loop is not working after the first entered message?
Thanks!
Class GameLeader:
public class GameLeader {
public static void main(String[] args) throws IOException {
GuessingPlayer guessingPlayer = new GuessingPlayer(userInterface);
String guess;
System.out.println("Please enter a startWord to begin!");
String startWord = userInterface.enterWord();
guessingPlayer.start();
while (attempts < 11) {
synchronized (guessingPlayer) {
System.out.println("It's your turn, Guessing Player!");
guessingPlayer.wait();
guess = guessingPlayer.message.toString();
if (startWord.contains(guess)) {
...
}
} else {
...
}
userInterface.mainMenu(guess);
}
}
}
}
Class GuessingPlayer:
public class GuessingPlayer extends Thread {
Message guessMessage;
private UserInterface userInterface;
GuessingPlayer(UserInterface userInterface) {
this.userInterface = userInterface;
}
#Override
public void run() {
synchronized (this) {
guessMessage = new Message(userInterface.enterWord());
notify();
}
}
}
I think you would be well served to review the course material on threads, and/or talk to your instructor. But, a few comments and suggestions:
I imagine the game leader is supposed to be a thread, and the player(s) are also supposed to be threads (as your current GuessingPlayer class is). These are all instantiated and started when your program starts by calling the start() method on the thread.
You don't have to call run, that gets called internally by the thread once it's started. But you probably want a loop in the run method that waits for the thread to be notified, and then repeats.
By "message passing" they mean something general like having a shared object or Queue that all the threads can read/write and have a reference to. One thread writes something in that object, and calls Thread.notify() to notify the other threads that something interesting has happened in that object. When that happens, the other thread will wake up right where it called the Thread.wait() method. Then it can check that shared object to see what's up.
http://web.mit.edu/6.005/www/fa14/classes/20-queues-locks/message-passing/
http://www.programcreek.com/2009/02/notify-and-wait-example/
Hope this helps.
You are using wait() method in a wrong way. You do not need an object reference to call wait() method. It is a method defined in Java's Object class.
Therefore, just write wait() instead of using guessingPlayer object reference.
Hope this helps. :)
I have a Thread scenerio , in which 3 classes are MainThread.java,NormalWorkerClass1.java,NormalWorkerClass2.java
1 class:
class MainThread implements Runnable
{
private Thread thread = null;
//private variables
..
..
//default Constructor
public MainThread(){}
public MainThread(int val){
this.val=val;
}
public void start() {
thread = new Thread(this,"rootthread");
thread.start();
}
#Override
public void run() {
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
try
{
while(true)
{
boolean retval=proccessSomething();
if(retval)
{
instance1.doMainProcess(arg..);
}
else
{
instance2.doMainProcess(arg..);
}
}
}
}
2 class:
class NormalWorkerClass1
{
private ...
private variables
public static NormalWorkerClass1 getInstance() {
return new NormalWorkerClass1();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass2
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
3 class:
class NormalWorkerClass2
{
private ...
private variables
public static NormalWorkerClass2 getInstance() {
return new NormalWorkerClass2();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass1
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
These are 3 classes.
My doubts are:
1 )In a multi threading Environment , i.e. if both class 2 and class 3 accessed at same time , whether
2 and 3 class cause any concurrency issue, because both are using some common methods and classes?
There is no Synchronisation part in this.
The web service part consists of another thread part.
2) What will happen when multiple thread access this,
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
because its getInstance() method is a static method ,
multiple threads will share NormalWorkerClass1 and NormalWorkerClass2 class object values ?
5)Both classes NormalWorkerClass1 and NormalWorkerClass2 calls same common methods.. for e.g.. web service part.. if a thread1 enters into web service part and takes some time to complete ..on that particular moment another thread2 came to use web service part..this might cause any problem in total execution . same case with mail part also..will cause any issue in object clashing. I know each thread has its own stack for execution and have copies of variables
4) Can this Code cause any performance bottleneck? If yes ,How can I improve this code for multi threading and performance improving environment. ?
as i am new to this threading concurrency part..
Where concurrency causes problems is when multiple threads access shared state, your example doesn't have any shared state, it just shows static methods returning new instances of things. If you add static class variables that are accessed concurrently then you will have to worry about thread-safety issues with threads overwriting each others' work or with changes not being visible to other threads.
Calling methods doesn't in itself introduce concurrency problems, accessing and changing the contents of instance and class variables is what causes problems.
Nathan's Hughes answer is correct. I would add that there may be a concurrency problem if your run() method touches any instance variables of the MainThread class.
And one more thing - maybe obvious, maybe not: concurrency is about threads, not classes. Both NormalWorkerClass1 and NormalWorkerClass2 cannot conflict with each other when they are called from the same thread.
I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
Another thread has following:
public void run(){
a.myCard = new Card(5);
}
What do you suggest?
You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card. Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.
The variable needs to be volatile when modifying from a different thread if you intend to poll for it, but a better solution is to use wait()/notify() or even a Semaphore to keep your other thread sleeping until myCard variable is initialized.
Looks like you have a classic producer/consumer case.
You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?
Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/
I have a main class in Android java project where all functions are defined. Then I have 2 other classes that extend the main class and implement Runnable.
main class: All main functions
class 2: I use all main functions and have a static variable X which I modify in file 2.
class 3: I use all main functions and have a static variable Y which I modify in file 3.
In the main class, I start 2 threads: one for Class2, and one for Class3.
When I try to call Class2.X from the main class, it is always null no matter what. I have tried volatile, synchronized(thread), getvalue(), etc. but it is not working.
What should I do to read the values of Class2.X such that it is not null from the main class?
Here is the code:
Thread t = new Thread(new Functionss(mRgbImage));
t.start();
Thread t2 = new Thread(new Functionss_2(mRgbImage));
t2.start();
if(boolean_variable)
{
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Bitmap final_added =addition(mRgbImage2, mRgbImage3);
mImageView.setImageBitmap(final_added);
mRgbImage2 and mRgbImage3 are the static volatile variables.
In fact, I think it is not a problem of variables because when i use an image in the main class and modify it, and then execute mImageView.setImageBitmap(initial_image) i am still getting a black screen on my android phone.
I have noted the following in the logcat:
Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#40a34d28
If I remove the threads, I don't get this error.
Any help?
I suspect that your threads are never executing the assignment statement or are assigning a different value or something. Maybe putting some log messages or debugging your application and putting a break point at the assignment would help.
If you had something like:
public class MainClass {
Class2 class2 = new Thread(new Class2());
class2.start();
class2.join();
// Class2.value will == 10 here
}
and then:
public class Class2 implements Runnable {
public static volatile int value;
public void run() {
...
this.value = 10;
...
}
}
Then after the assignment happens in Class2 then the value will have been updated. This is obviously a simple example and I suspect the Class2 thread has not actually finished in your code, but as long as the assignment has been reached then value will have been changed. Again, log messages or debugger would help here.
It would be better to have something like the following pattern:
public class Class2 implements Runnable {
private volatile int value;
public void run() {
...
this.value = 10;
...
}
public int getValue() {
return this.value;
}
}
So then MainClass can access the value from Class2 and Class3 without confusion. Notice that you still need the volatile keyword there because the value is being get/set from different threads.
Hope something here helps. If you edit your question with more details I may be able to help more.
I was using JJIL library and it turned out that
"
What steps will reproduce the problem?
Use RgbImageJ2se.toDisplay in multiiple threads simulatenous (different instances of RgbImageJ2se).
Due to the static reference to the Graphics object passed, there will be indeterminate results depending on which thread executes first.
"
Reference: http://code.google.com/p/jjil/issues/detail?id=27
I doubted it has to do with libraries because i rewrote the code with math functions instead and the output was right. it was waiting for both classes to finish and use their output to do further calcuations.
Hope this helps someone else stuck.
I hope this is going to be enough information, so here it goes. If you need more info, lemme know in the comments.
I have a class that has two inner classes. The inner classes each have two methods that call a method in the outer class. So, it looks like this:
public OuterClass {
private boolean outerMethodHasBeenCalled = false;
private void outerMethod() {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
private FirstInnerClass {
public void someMethod() {
outerMethod();
}
}
private SecondInnerClass {
public void someOtherMethod() {
outerMethod();
}
}
}
It's important to note that:
This is for an Android app. Instances of FirstInnerClass and SecondInnerClass are passed to a WebView as a JavaScript interface, so someMethod and someOtherMethod can be called at any time, in no particular order.
I currently have a problem with the existing code (without the synchronized keyword) where outerMethod is called pretty much at the exact same time (I print out a log message, and they're timestamped to the 1000th of a second) by different objects. My app then 'does stuff' twice because outerMethodHasBeenCalled is still false when outerMethod was called. This is not okay, and it is exactly what I'm trying to prevent. My app should only 'do stuff' once and only once: the first time outerMethod is called.
It might sound like I have multiple instances of OuterClass, but rest assured that it's only one instance of OuterClass.
It's important that my app 'does stuff' only the first time outerMethod gets called (I hope that's evident by now). All subsequent calls are essentially ignored. Whichever inner class calls outerMethod first -- doesn't matter.
So, is it appropriate to use the synchronized keyword in this case?
Yup, given what you've laid out above, I'd go with:
private synchronized void outerMethod() {
...
}
Note, this will have the side-effect of blocking one of the callers until the outerMethod() completes. If that is acceptable, cool. If the intent is merely that the code in outerMethod() is run once, and it is OK for the second caller not to be delayed if the first caller is running outerMethod(), you might consider:
public OuterClass {
private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
private void outerMethod() {
if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
// do stuff
}
}
...
See the JavaDoc for AtomicBoolean to grok what is going on there (assuming it is available in Android's Java).
Wrap everything in outerMethod that you want to run only once in a synchronized block:
private void outerMethod() {
synchronized (this) {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
}
That way, the first time the method is called, only one thread will be allowed into the synchronized block at a time. The first one will execute the code in the if statement, then set outerMethodHasBeenCalled to true. The other threads will see that it is true, and skip the if code.