trouble in wait and notify in java

Discussion in 'Mac Programming' started by pricelessjunk, Aug 2, 2009.

  1. pricelessjunk macrumors newbie

    Joined:
    Aug 2, 2009
    #1
    Maybe posts like this have been posted before but am really stuck with this..so i need help please...

    I have a simple applet code..it marquees a line...i want to make it stop at a particular interval and make it continue on mouse clicking...so I use wait()..but on using notify() nothing happens...can anyone plz help...and forgive me if there is any stupid errors in the code...


    Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.applet.*;
    
    public class Applet4S extends Applet implements MouseListener{
        
        String msg;
        int x=20,y=30,i;
    
        
        public void init()
        {
            setForeground(Color.blue);
              addMouseListener(this);
        }
        
            public void paint(Graphics g)
        {
            g.drawString(msg, x, y);
        }
            
            public void mouseExited(MouseEvent me){}
            public void mouseEntered(MouseEvent me){}
            public void mousePressed(MouseEvent me){}
            public void mouseReleased(MouseEvent me){}
            
            public void mouseClicked(MouseEvent me)
            {
                showStatus("Mouse is clicked");
                resumenow();
            }
            
            synchronized void resumenow()
            {
                notify();
            }
            
            synchronized void suspendnow()
            {
            try 
            {
                showStatus("Thread is in suspendnow()");
                wait();
            } 
            catch (InterruptedException ex) {}
            }
            
        public void start()
        {
            msg = "Started";
            
            
            for(i=0;;i++)
            {
                if(x>200)
                {
                    x=20;
                }
                x=x+1;
                repaint();
                if(i%5==0)
                {
                    showStatus("This thread is gonna wait");
                    suspendnow();
    
                }
            }
           
       }
        
    }
    Thanks in advance...
     
  2. whitehexagon macrumors regular

    whitehexagon

    Joined:
    May 12, 2007
    #2
    I think your wait and notify should be from different threads, currently it looks like they are both on the 'event dispatch thread' A less complex approach might just to check a boolean flag for wether to incremnt your x value or not ?
     
  3. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #3
    thank u very much fr replying....I have tried out the way you hav told me...but it seems that whnevr i put in an infinite loop, the screen in the applet viewer goes white and does not display anything at all...moreover, it does not even respond to mouse clicks....
    However, i had a slight idea that i was goin wrong with wait() where u said i was...culd you plz help me with the multithreaded version of this prog...am really sry fr bothering u again...
     
  4. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #4
    hey...i tried out the multi thread version...but i am again getting the same prob...the thread goes into wait..but dosen't wake up...where am i goin wrong...somebody plzz help...

    Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.applet.*;
    
    
    public class threadtest extends Applet implements MouseListener{
        
        String msg,statusmsg;
        int x=20,y=30,i;
        newthread nt=new newthread();
        
        public void init()
        {
            setForeground(Color.blue);
            addMouseListener(this);
        }
        
            public void paint(Graphics g)
        {
            g.drawString(msg, x, y);
                           
         }
            
            public void mouseExited(MouseEvent me){}
            public void mouseEntered(MouseEvent me){}
            public void mousePressed(MouseEvent me){}
            public void mouseReleased(MouseEvent me){}
            
            public void mouseClicked(MouseEvent me)
            {
                showStatus("Mouse is clicked");
                msg="look at the mouse";
                repaint();
                nt.t.start();                             //Calling the run() in newthread
            }
            
            synchronized void resumenow()
            {
                notify();
            }
            
            synchronized void suspendnow()
            {
            try 
            {
                showStatus("Thread is in suspendnow()");
                wait();
            } 
            catch (InterruptedException ex) {}
            }
    
        
        
        public void start()
        {
            msg = "Started";
            
            
            for(i=0;i<100;i++)
            {
                if(x>200)
                {
                    x=20;
                }
                x=x+1;
                repaint();
                if(i%3==0)
                {
                    showStatus("This thread is gonna wait");
                    repaint();
                    suspendnow();
                    showStatus("thread is waiting");
    
                }
            }
    
        }
    }
    
    
    
    class newthread implements Runnable{
        
        Thread t;
        
        public newthread()
        {
              t=new Thread(this);
        }
        
        public void run()
        {
           resumenow();
        }
        
        synchronized void resumenow()
        {
            notifyAll();
        }
    
         synchronized void suspendnow()
         {
             try
             {
                 wait();
             }
             catch (InterruptedException ex) {}
         }
        
    }

    sombody plzzz help...
     
  5. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #5
    Can you post the source file where your main is defined, so we can see how threadtest is being run? Also, can you put things in [CODE][/CODE] tags instead of quotes?

    In the meantime, you might take a look at this:
    http://www.java-samples.com/showtutorial.php?tutorialid=306

    You'd need to have something outside of threadtest call resumenow from a still-running thread when you're ready for execution in the thread that called wait() to continue.

    -Lee
     
  6. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #6
    hey...thnx fr replying...I replaced the QUOTE tags with the CODE tags as u said...

    actually this is an applet code...so no main is present...this code cn be run by an applet viewer or frm the html usng <APPLET> tags....

    I tried calling the resumenow from the newthread class...but it still dosen't wrk...plzzz help...
     
  7. whitehexagon macrumors regular

    whitehexagon

    Joined:
    May 12, 2007
    #7
    the problem is that you don't want to call wait on the EventDispatchThread becuase that will block the GUI responses and rendering. Threading in Java can appear quite simple, but also tricky to get right. So think about what you are trying to do a bit more before launching into a multithreaded approach.

    Is it not enough that you have a boolean, when false x is not incremented, when true x is incremented? I dunno, I'm not sure from your code what effect you are trying to acheive.

    If you really want to get into threading then best to use some of the included thread libs. Have a look at Executors. you might find something usefull for scheduling an x update every 50 milliseconds for example.

    But if you want to fix what you are doing then try to get your second thread up and running already in the init, have that thread looping with a Thread.sleep/yield between updates to x. x could be made volatile since it's been updated and used from 2 different threads. Then include a boolean (also volatile or have a look at AtomicBoolean) check inside the same loop for wether it should be incrementing x or not. That means the only thing your eventDispathThread is doing is rendering and responding to mouse click. ie no wait/notify complexity. Hope that makes sense...
     
  8. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #8
    Thnx again fr replying...wht ur suggesting is basically a form of polling....I have tried it out and did it successfully...

    howevr, I am still looking forward to use the wait() and notify() as i believe it would be more efficient...so if possible..can u plzz walk me through the wait/notify complexity as u did with this...thnxxx in advance..
     
  9. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    You need to break things down a bit differently. You can't put your main thread to sleep, as nothing will ever be able to wake it back up. I think this code achieves what you want. I am not that familiar with java threading, so i don't know if incrementX, etc. are "safe", but with only one worker thread it should be OK.

    Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.applet.*;
    
    
    public class threadtest extends Applet implements MouseListener{
        
        String msg,statusmsg;
        int x=20,y=30;
        threadtest.newthread nt;
    
        public synchronized void incrementX() {
          x=x+1;
        }
    
        public synchronized void setX(int newX) {
          x=newX;
        }
    
        public synchronized int getX() {
          return x;
        }
        
        public void init()
        {
          setForeground(Color.blue);
          addMouseListener(this);
        }
        
        public void paint(Graphics g)
        {
          g.drawString(msg, x, y);
        }
            
        public void mouseExited(MouseEvent me){}
        public void mouseEntered(MouseEvent me){}
        public void mousePressed(MouseEvent me){}
        public void mouseReleased(MouseEvent me){}
            
        public void mouseClicked(MouseEvent me)
        {
          showStatus("Mouse is clicked");
          msg="look at the mouse";
          repaint();
          nt.wakeUp();
        }
            
        public void start()
        {
          msg = "Started";
          nt = new threadtest.newthread(this);
        }
    
    
    
      class newthread implements Runnable{
          
          Thread t;
          threadtest parentObject;
      
          newthread(threadtest tt) {
            parentObject = tt;
            new Thread(this).start(); 
          }
      
          newthread() throws javax.naming.OperationNotSupportedException {
            throw new javax.naming.OperationNotSupportedException();
          }
      
          public synchronized void wakeUp() {
            notify();
          }
    
          public void run() {
            doWork();
          }
    
          private synchronized void doWork() {
            int i = 0; 
            while(true) {
              i++;
              if(parentObject.getX()>200) {
                parentObject.setX(20);
              }
              parentObject.incrementX();
              parentObject.repaint();
              if(i%3==0) {
                i=0;
                parentObject.showStatus("This thread is gonna wait");
                parentObject.repaint();
                try {
                  wait();
                } catch (java.lang.InterruptedException ie) {
                  parentObject.showStatus("Worker was interupted!");
                }
                parentObject.showStatus("Worker thread is awake again!");
              }
            }
          }
      }
    }
    
    -Lee
     
  10. iShater macrumors 604

    iShater

    Joined:
    Aug 13, 2002
    Location:
    Chicagoland
    #10
    Just remember there is no guarantee your thread will start off immediately after you click the button.
     
  11. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #11
    thnk u sooo veryyyyyyy muchhh.....the code is brilliantly crafted...just 1 last trouble i will give thee...

    Code:
    newthread() throws javax.naming.OperationNotSupportedException {
            throw new javax.naming.OperationNotSupportedException();
          }
    forgv me if i am asking somthn very obvious as i am still learning...i exactly dnt understand what dis means and the utility of this...is it imp to have in the code...

    thnk u again fr helping me out...
     
  12. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #12
    That piece was probably not necessary, and the exception I chose may have been poor. The idea was to prevent the invocation of a newthread without passing in a threadtest object, since the functionality of newthread is inexorably tied to a "parent" threadtest object. I haven't spent much time in java lately, so simply leaving out a constructor with no arguments may have worked just as well.

    -Lee
     
  13. pricelessjunk thread starter macrumors newbie

    Joined:
    Aug 2, 2009
    #13
    thnk u very much...nw tht i am ovr that i cn get on with my actual wrk....thnxxx again...
     

Share This Page