Results 1 to 8 of 8
  1. #1
    nicoeschpiko is offline Member
    Join Date
    Dec 2010
    Location
    New Engaland
    Posts
    11
    Rep Power
    0

    Default Using Thread waiting() method

    THIS POST HAS BEEN EDITED TO MORE DIRECTLY ADDRESS THE MAIN ISSUE, AND PROVIDE RUNNABLE CODE

    I am trying to send a notify to an available Thread (first Thread i can find in a pool currently in a WAITING state), but am unable to. I am trying to send the notify alert to a thread running in a separate class, although this class is included in the same package. Here is the Server.java file from which I am trying to notify my available thread:

    ***************Server.java***********************
    Java Code:
    package dir.test;
    
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    
    public class Server {
    	static private final int THREADCOUNT=5;
    
    
    	public static void main(String[] args) throws InterruptedException {
    		ArrayList<Thread> objThreads = new ArrayList<Thread>(THREADCOUNT);
    
    		for (int i=0; i<THREADCOUNT; i++) {
    			objThreads.add(i, new Thread(new ObjThread(1)));
    			objThreads.get(i).start();
    		}
    
    		try {
    			for (int i=0; i<objThreads.size(); i++) {
    				if ( (objThreads.get(i).getState())==Thread.State.WAITING ) {
    					System.out.println("Thread " + i + " is in state: WAITING.");
    					objThreads.get(i).notify();
    					System.out.println("Thread " + i + " has been notified.");
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} catch (Throwable t) {
    			System.err.println("Caught throwable t: " + t);
    		}
    	}
    }
    **********************************************

    and here's the ObjThread.java file...

    ***************ObjThread.java********************* **
    Java Code:
    package dir.test;
    
    import java.lang.Runnable;
    import java.util.*;
    
    
    public class ObjThread implements Runnable {
    	private int int_var;
    
    	public ObjThread(int int_var) {
    		this.int_var = int_var;
    	}
    
    	public synchronized void run() {
    		while ( true ) {
    			try {
    				System.out.println("test...before wait");
    				wait();
    				System.out.println("test...after wait.  int variable value: " + int_var);
    			} catch ( InterruptedException e ) { }
    		}
    	}
    }
    **********************************************


    The thread never gets to the statement:
    System.out.println("test...after wait. int variable value: " + int_var);

    My output is:
    $ java dir.test.Server
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    Thread 0 is in state: WAITING.
    java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at dir.test.Server.main(Server.java:23)



    Any idea how I can wake a thread from a WAITING state with this file structure so it can resume it's work?
    Last edited by nicoeschpiko; 12-11-2010 at 04:22 PM.

  2. #2
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,785
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by nicoeschpiko View Post
    java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at dir.test.Server.main(Server.java:23)[/B]
    You can't notify anything if you don't hold the lock on that object, i.e. first you have to synchronize on the object and only then you can notify other threads (if any) waiting on that object.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  3. #3
    nicoeschpiko is offline Member
    Join Date
    Dec 2010
    Location
    New Engaland
    Posts
    11
    Rep Power
    0

    Default

    Thanks. I have changed the try block in Server.java to read:
    Java Code:
    for (int i=0; i<objThreads.size(); i++) {
    	if ( (objThreads.get(i).getState())==Thread.State.WAITING ) {
    		System.out.println("Thread " + i + " is in state: WAITING.");
    		synchronized( objThreads.get(i) ) {
    			objThreads.get(i).notify();
    			System.out.println("Thread " + i + " has been notified.");
    			break;
    		}
    	}
    }
    and the line adding a thread to the ArrayList to:
    Java Code:
    objThreads.add(i, new Thread(new ObjThread(i)));
    so that I can tell which thread is being notified in the ObjThread.java code.

    I am not getting an error anymore, but am still not seeing the following line being executed in ObjThread.java:
    System.out.println("test...after wait. int variable value: " + int_var);

    in the output. Here is my output:
    $ java dir.test.Server
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    Thread 1 is in state: WAITING.
    Thread 1 has been notified.


    Please let me know if you would like the two modified files posted in their entirety. Thanks again for your help!

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,785
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by nicoeschpiko View Post
    and the line adding a thread to the ArrayList to:
    Java Code:
    objThreads.add(i, new Thread(new ObjThread(i)));
    so that I can tell which thread is being notified in the ObjThread.java code.
    You're synchronizing on a Thread object and you call notify on it; while this is not illegal, no Thread is waiting, an ObjThread is waiting so you should synchronize and notify on that object.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  5. #5
    nicoeschpiko is offline Member
    Join Date
    Dec 2010
    Location
    New Engaland
    Posts
    11
    Rep Power
    0

    Default

    if objThreads.get(i) gives me the thread associated with the instance of the object I want to notify, what is the statement I use to obtain it's respective object instance that I then use to synchronize? I've browsed through all of the methods following objThreads.get(i). but could not find what I think I'm looking for.

  6. #6
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,785
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by nicoeschpiko View Post
    if objThreads.get(i) gives me the thread associated with the instance of the object I want to notify, what is the statement I use to obtain it's respective object instance that I then use to synchronize? I've browsed through all of the methods following objThreads.get(i). but could not find what I think I'm looking for.
    I don't know; there is no getRunnable() or getTarget() method in the Thread class; you have to reorganize your code a bit (or extend the Thread class to create the wanted functionality).

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  7. #7
    nicoeschpiko is offline Member
    Join Date
    Dec 2010
    Location
    New Engaland
    Posts
    11
    Rep Power
    0

    Default

    Sounds like I'll have to reorganize the code.

    I'll provide a bit more context to explain the structure in which the code needs to exist for an assignment. The Server collects requests to do a job. These requests are added to a queue (of type ArrayList) object in the Server. As soon as there is something in the queue, the Server must directly or indirectly inform the waiting threads in the ObjThread class that there is a job waiting in the queue. Much of this code has been stripped from the example provided w/the intention of not distracting from the issue of notifying a waiting thread. I probably should have started w/this explanation, and for this I apologize.

    So, w/those requirements, how can I notify a waiting thread to continue w/it's job from the Server? If I can't retrieve an object associated w/one of the waiting threads, it seems I must create a new instance of ObjThread. I've tried creating one in the code:

    Java Code:
    try {
    	for (int i=0; i<objThreads.size(); i++) {
    		if ( (objThreads.get(i).getState())==Thread.State.WAITING ) {
    			System.out.println("Thread " + i + " is in state: WAITING.");
    			ObjThread objtd = new ObjThread(10);
    			synchronized( objtd ) {
    				objtd.notifyObjThread();
    				System.out.println("Thread " + i + " has been notified.");
    				break;
    			}
    		}
    	}
    } catch (Exception e) {
    	e.printStackTrace();
    } catch (Throwable t) {
    	System.err.println("Caught throwable t: " + t);
    }
    in Server.java

    and the function:
    Java Code:
    public void notifyObjThread() {
    	notify();
    }
    in ObjThread.java, but keep getting the same output:

    $ java dir.test.Server
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    test...before wait
    Thread 0 is in state: WAITING.
    Thread 0 has been notified.


    Where the statement:
    System.out.println("test...after wait. int variable value: " + int_var);

    is not displayed indicating that the thread doesn't resume.

  8. #8
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,785
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by nicoeschpiko View Post
    Sounds like I'll have to reorganize the code.

    I'll provide a bit more context to explain the structure in which the code needs to exist for an assignment. The Server collects requests to do a job. These requests are added to a queue (of type ArrayList) object in the Server. As soon as there is something in the queue, the Server must directly or indirectly inform the waiting threads in the ObjThread class that there is a job waiting in the queue. Much of this code has been stripped from the example provided w/the intention of not distracting from the issue of notifying a waiting thread. I probably should have started w/this explanation, and for this I apologize.
    No need to apologize; did you read the API documentation for the classes in the java.util.concurrent package? There are classes in there that can do the job for you and you don't have to mess around with synchronizing, waiting and locking yourself anymore, those classes do that for you.

    If you insist on doing it yourself, your main problem now is that given a Thread you want to retrieve the ObjThread which is the Runnable for the Thread, right? Simple extend the Thread class a bit:

    Java Code:
    public class MyThread extends Thread {
       private Runnable runnable;
       public MyThread(Runnable runnable) {
          super(Runnable);
          this.runnable= runnable;
       }
       public Runnable getRunnable() { return runnable; }
    }
    Wrap your ObjThread object in a MyThread and when you fetch it from your List fetch the Runnable from it (it is one of your ObjThread objects) and you're in business.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

Similar Threads

  1. Thread problem, calling method in run method
    By majk in forum Threads and Synchronization
    Replies: 4
    Last Post: 09-27-2010, 12:40 PM
  2. Trigger main thread method from secondary thread?
    By DigitalMan in forum Threads and Synchronization
    Replies: 8
    Last Post: 01-26-2010, 03:13 AM
  3. Thread RUNNABLE or WAITING
    By Pushkar in forum Threads and Synchronization
    Replies: 10
    Last Post: 01-14-2010, 02:36 AM
  4. [SOLVED] Method from one thread called on another thread
    By Ypsilon IV in forum Threads and Synchronization
    Replies: 7
    Last Post: 04-24-2009, 03:07 PM
  5. Once again: waiting in a thread loop.
    By willemjav in forum Threads and Synchronization
    Replies: 115
    Last Post: 09-22-2008, 02:35 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •