LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Java threads, why does this work/not work? (http://www.linuxquestions.org/questions/programming-9/java-threads-why-does-this-work-not-work-831205/)

crackinggear 09-09-2010 11:57 AM

Java threads, why does this work/not work?
 
Hi!

I'm writing a program to learn about threads in Java, consisting of one Main class and two different thread implementations (T1 and T2).

T2 is the one I have problems with. I have included a method in the class to allow me to pause the thread, and another method to stop the thread from running entirely. I've accomplished this by nesting a loop inside a loop in the run-method, and two booleans set by those methods I mentioned.

The problems is that if I pause the thread and then try to resume it it just won't do the things in the inner loop (as it should while not paused). But, and here comes the mystery, it works if I add a dummy line system.out.print(""); inside the outer loop. Further on, if I don't add the dummy line the thread won't terminate when told to and I can only exit the program by forcing it to.

Any ideas as to why it works, or doesn't work?

Platform: Mac OS X Snow Leopard, javac 1.6.0_20, java JRE 1.6.0_20-b02-279-10M3065

Here comes what I think is the relevant code...

Excerpt from Main.java - main-method
Code:

T2 t2 = new T2(); //Create and start thread T2

Thread.currentThread().sleep(5000); //Wait...

t2.toggleRunning(false); //Pause the thread T2

Thread.currentThread().sleep(5000); //Wait...

t2.toggleRunning(true); //Resume running T2

Thread.currentThread().sleep(5000); //Wait...

t2.kill(); //Stop running T2

Excerpt from T2.java
Code:

public class T2 implements Runnable {

 private Thread t = new Thread(this);
 private boolean alive;
 private boolean running;

 //Constructor: t.start(); alive = true; running = true;

 public void kill() {
  this.running = false;
  this.alive = false;
 }

 public void toggleRunning(boolean running) {
  this.running = running;
 }

 public void run() {
  while(this.alive) {
  System.out.print(""); // <<<<<****** DUMMY LINE
  if(this.running) {
    System.out.println("T2 running");
    try { Thread.currentThread().sleep(1000); } catch(Exception e) {}
  }
  }

}

Any help appreciated! =)

//Nicholas

EDIT: I tried on Debian Linux now as well with javac 1.6.0_20 and java JRE 1.6.0_20-b02 - it works perfectly there - bug in the Mac version?

ntubski 09-10-2010 05:58 AM

You are accessing variables from 2 different threads, therefore your program has undefined behaviour. The VM is probably caching the variable in a thread-local cache. Adding statements (the dummy statement) may cause the system not to cache the variable. A different system may decide not to cache the variable. If you declare the variable volatile it will never be cached. See Typical use of volatile in Java.

crackinggear 09-10-2010 03:52 PM

You're great! =)

Thank you very, VERY much!

I learn something new every day... =)


All times are GMT -5. The time now is 12:25 PM.