9 Replies - 586 Views - Last Post: 12 February 2011 - 08:07 PM Rate Topic: -----

#1 kswi223  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 27-April 10

Java Concurrency

Posted 12 February 2011 - 06:55 PM

New to Java Concurrency!
This is a class assignment where I need to use wait() and notify() in this code. The output I'm getting is:
Thread 0 is here

The output should be:
Thread 0 is here
Thread 1 is here
Thread 2 is here
Thread 3 is here
repeat above 9 more times.

When I debugged the code, the 2nd time wait() executes, the program stops completely.
Any help on how to get the correct output will be appreciated. If I need to clarify something, let me know.
Thank You

/** Experiment with threads.
 * NOTE: there is no guarantee this will actually work as expected.
 */
public class MyThreadY extends Thread {
  private static final int NUM_ITERS = 10;
  //private static final int SLEEP_INCREMENT = 100; // 0.1 sec

  private static int turn = 0;

  private int myNumber;
  private int total;

  public MyThreadY(int num, int tot) {
    this.myNumber = num;
    this.total = tot;
  }

  public synchronized void run() {
    for (int i=0; i<NUM_ITERS; i+=1) {
      while (turn != myNumber) 
	try {
		wait();
	} catch (Exception ignored) {};
      /* turn == myNumber */ 
      System.out.println("Thread " + myNumber + " is here!");
      turn = (turn + 1) % total;  // let someone else have a turn...
      notifyAll();
    }
  }
}



Is This A Good Question/Topic? 0
  • +

Replies To: Java Concurrency

#2 moobler  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 143
  • View blog
  • Posts: 224
  • Joined: 21-January 11

Re: Java Concurrency

Posted 12 February 2011 - 07:04 PM

What code are you using to run these threads - can you post your main method?
Was This Post Helpful? 1
  • +
  • -

#3 kswi223  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 27-April 10

Re: Java Concurrency

Posted 12 February 2011 - 07:08 PM

Thank you for replying.
public class TesterY {
  private static final int NTHREADS = 4;

  public static void main(String[] args) {

    // create the appropriate number of threads
    for (int i=0; i<NTHREADS; i+=1) {
      new MyThreadY(i,NTHREADS).start();
    }

  } // main

} // class Tester


Was This Post Helpful? 0
  • +
  • -

#4 moobler  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 143
  • View blog
  • Posts: 224
  • Joined: 21-January 11

Re: Java Concurrency

Posted 12 February 2011 - 07:33 PM

This was the first time I've ever actually used wait or notifyAll, so I see why you were having trouble getting it to do something.

It basically comes down to this: you do not want to call the local wait or notifyAll methods. You need to define some object (it doesn't matter what type) that is accessible to each individual thread. This object is known as the 'monitor' and each thread should only call wait or notify on the monitor.

When one thread calls monitor.wait(), then that thread is "waiting on" the monitor. It will continue waiting until something tells the monitor to notify waiting objects.
Was This Post Helpful? 2
  • +
  • -

#5 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3116
  • View blog
  • Posts: 19,153
  • Joined: 14-September 07

Re: Java Concurrency

Posted 12 February 2011 - 07:44 PM

Why are you synchronizing the run() method? The threads aren't sharing that as a resource. Using it means "only execute this by any one thread at a given time", in this case you're blocking all but one from running, defeating the purpose of multithreading in the first place.

The initial way to do this is to make them sleep for different periods of time:

//runs forever
//could fine tune the interweaving 
class MyThread implements Runnable{
    	private static int turn = 0;
    	private int num, total;
    	
    	public MyThread(int n){
    		num = n;
    		total = 4;
    	}
    	
    	public void run(){
    		try{
	    		while(true){
	    			if (num == turn){
	    				 printMe(Thread.currentThread());
	    				 turn = (turn + 1)%total;
	    				 Thread.sleep(50);
	    			}
	    			else Thread.sleep(1500);
	    		}
    		}catch(Exception e){e.printStackTrace();}
    		
    		
    	}
    	public synchronized void printMe(Thread target){
			System.out.println(target.getName());
		}
}
   
class Test{
    public static void main(String[] args) {
 		for(int i = 0; i < 4; i++){
 			new Thread(new MyThread(i)).start();
 		}
    }
}



If you unsynchronize run() you'll notice you get some nasty exceptions. This is because wait/notify require an object to sit on.


So, with that in mind:

//runs forever
class MyThread implements Runnable{
    	private static int turn = 0;
    	private int num, total;
    	private Object monitor;
    	
    	public MyThread(int n, Object mon){
    		num = n;
    		total = 4;
    		monitor = mon; //give them all the same one
    	}
    	
    	public void run(){
    		synchronized (monitor){
	    		try{
		    		while(true){
		    			if (num == turn){
		    				 printMe(Thread.currentThread());
		    				 turn = (turn + 1)%total;
		    				 monitor.notifyAll();
		    			}
		    			else monitor.wait();
		    		}
	    		}catch(Exception e){e.printStackTrace();}
    		}
    		
    	}
    	
    	public synchronized void printMe(Thread target){
			System.out.println(target.getName());
		}
}
   
class Test{
    public static void main(String[] args) {
    	Object monitor = new Object();
 		for(int i = 0; i < 4; i++){
 			new Thread(new MyThread(i, monitor)).start();
 		}
    }
}



Output:

Quote

Thread-0
Thread-1
Thread-2
Thread-3
Thread-0
Thread-1
Thread-2
Thread-3
Thread-0
Thread-1
Thread-2
Thread-3
Thread-0
Thread-1
Thread-2
Thread-3
Thread-0
Thread-1
Thread-2
Thread-3

//on to infinity


Notice that they're always in correct order (in this case, chronologically, which is the behavior I desired).

I'll leave it as an exercise to the reader to limit the number of times this outputs.
Was This Post Helpful? 3
  • +
  • -

#6 kswi223  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 27-April 10

Re: Java Concurrency

Posted 12 February 2011 - 07:48 PM

Unfortunately I have to use these two functions. Thank you for your response, I think I understood your advice. I used
"this" as the monitor. Although I'm still getting the same output. I have also tried moving the notify() function to different
parts of the code, but I'm still crashing when wait() is executed the 2nd time. Frustrating! lol
Below is the changes I made.

/** Experiment with threads.
 * NOTE: there is no guarantee this will actually work as expected.
 */
public class MyThreadY extends Thread {
  private static final int NUM_ITERS = 10;
  //private static final int SLEEP_INCREMENT = 100; // 0.1 sec

  private static int turn = 0;

  private int myNumber;
  private int total;

  public MyThreadY(int num, int tot) {
    this.myNumber = num;
    this.total = tot;
  }

  public synchronized void run() {
    for (int i=0; i<NUM_ITERS; i+=1) {
      while (turn != myNumber) 
	try {
		this.wait(); //used this as monitor
	} catch (Exception ignored) {};
      /* turn == myNumber */ 
      System.out.println("Thread " + myNumber + " is here!");
      turn = (turn + 1) % total;  // let someone else have a turn...
      this.notifyAll(); //used monitor this
    }
  }
}


Was This Post Helpful? 0
  • +
  • -

#7 moobler  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 143
  • View blog
  • Posts: 224
  • Joined: 21-January 11

Re: Java Concurrency

Posted 12 February 2011 - 07:51 PM

Calling this.wait() is the same as just calling wait(). Like I said, you have to use an object that is shared by all threads.
Was This Post Helpful? 1
  • +
  • -

#8 kswi223  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 27-April 10

Re: Java Concurrency

Posted 12 February 2011 - 07:52 PM

Thank you KYA for your reply. I completly agree that sleep() is the better method, but my assignment requires me
to use the wait() notify() functions.
Was This Post Helpful? 0
  • +
  • -

#9 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3116
  • View blog
  • Posts: 19,153
  • Joined: 14-September 07

Re: Java Concurrency

Posted 12 February 2011 - 07:55 PM

"better" is subjective. If you want to guarantee rather then highly recommend ordering then wait()/notify() is the way to go. Giving the threads enough sleep time is ok for something like this, but as soon as things get "more complex" this may not be the case.
Was This Post Helpful? 1
  • +
  • -

#10 kswi223  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 27-April 10

Re: Java Concurrency

Posted 12 February 2011 - 08:07 PM

I finally got the program to work. I created an object that all the threads share to call
monitor.wait() and monitor().notify. Thank you both Moobler and KYA for your advice and code examples.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1