Results 1 to 14 of 14

Thread: Thread

  1. #1
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default Thread

    I have a FrontEnd class and a Play class, which extends Thread.

    In FrontEnd, I create an object of Play and then use the start() method of Thread, which calls the run() method of my Play object. This run() method then executes in another thread, and it's great.

    But if I then use the pause() method of my Play object, which stops the music, but doesn't directly do anything to do with the Thread, the Thread "dies." If I try to run any of it's methods thereafter, they run in the same thread as FrontEnd, and it throws an (iirc) IllegalStateException if I use the start() method again...

    How can I either stop the Thread from dying, or revive it when I need it again?

  2. #2
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    A thread essentially has a single "life cycle": once you start it, it runs its course, then exits. So to implement a pause, you essentially have to "manage it" yourself. Different possibilities are:
    - to "pause" the thread, just signal to it that you want it to exit; when the user then "unpauses" the thread, start a new one to continue where the old one left off; if your thread can periodically check a "please pause" variable, then you can check this; if it's pulling items off a queue, you can put a special "please pause" object on the queue (if you'll forgive the plug, see my web page on stopping a thread);
    - instead of signalling to the thread to stop, the signal is to "pause"; when it receives a "pause" notification, use the wait/notify mechanism to make the thread wait on an object for a "please continue" signal -- this is obviously slightly more involved, but avoids creating a new thread each time (though for a music player occasionally paused by the user, that actually wouldn't be so bad I don't think) -- again, I have a few pages on wait/notify in case they help, but the essential idea is:
    Java Code:
    public class MusicThread extends Thread {
      private Object pauseObj = new Object();
    
      public void pleasePause() {
        postNote(PAUSE_REQUEST);
      }
      public void pleaseResume() {
        synchronized (pauseObj) {
          pauseObj.notifyAll();
        }
      }
    
      public void run() {
        while (!stopRequested) {
          Note n = nextNote();
          if (n == PAUSE_REQUEST) {
            synchronized (pauseObj) {
              pauseObj.wait(); // wait for a "resume" notification
            }        
          }
        }
      }
    }
    I've obviously ignored various details + exceptions. Your method to make the thread stop completely would need to set the 'stopRequest' flag then interrupt() that thread.

  3. #3
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    P.S. You could obviously post an "EXIT_REQUEST" item to the note queue as well -- that might be neater than the 'stopRequested' flag.

  4. #4
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    Thanks, I'll look into all of that later. What if I just want to keep the thread alive? Is that bad programming or something?

    What I intended to do was to keep the thread alive, even when it isn't actually playing music... That was the response when the 'play' button is clicked should be quicker, although it may waste a bit of system resources while the music isn't playing... I hope I'm making sense.

  5. #5
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    It depends a bit on what you mean by "keep alive". If you mean "sit in a tight loop, continually checking a variable", then that's definitely bad because you'll sit burning the CPU and having a negative impact on the rest of the system.

    I don't think you have to worry about responsiveness. On most systems, starting a new thread or (especially) notifying an existing thread will happen within milliseconds, if not microseconds.

  6. #6
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    OK never mind about that, I'm still grasping the Thread class.

    I tried on my own to make a pause method in the FrontEnd class that goes something like this:

    Java Code:
    synchronized(player) {//player is my object of the Player class
        player.wait();
    }
    and here's a portion of the play method:

    Java Code:
    synchronized(player) {//player is my object of the Player class
        player.notify();
    }
    Thus I could start the music and pause it, but when I tried to start it again using the above method, it ran in the same thread and froze the FrontEnd class while the music played...

    I'll give your method a try then...

  7. #7
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    No, the wait() needs to go inside the run() method of your thread, in response to it being asked to pause. Whenever you call wait(), it's always the current thread that actually does the waiting.

  8. #8
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    I tried the code you posted way above but, even with some fiddling, no luck.
    Where does the postNote method come from? I tried to substitute a boolean:

    Java Code:
    boolean pause = false;
    void pleasePause() { pause = true; }
    
    public void run() {
        if (pause) {
            wait();
        }
    }
    But that didn't work.

    Could I use an ArrayList of booleans, and wait() when it becomes true:

    Java Code:
    ArrayList<boolean> pause = new ArrayList();
    void pleasePause() { pause.add(true); }
    public void run() {
        for (int i =0; i < pause.size(); i++) {
            if (pause.get(i)) {
                wait();
            }
        }
    }
    I don't expect that to work, just tossing it out there...

    Please further explain; until this morning I didn't even know that the Thread class existed, so I'm still grasping how it works...

    Much appreciated.

    Here's what I had:
    Music class:
    Java Code:
    static AdvancedPlayer player = null; //this is the object that plays the music
    
    void initialize() {
    	player = new AdvancedPlayer(musicFile);
    }
    
    public void run() { resumeSong(); }
    
    void resumeSong() { player.play(); }
    
    void pauseSong() { player.close(); }
    FrontEnd class:
    Java Code:
    Music music = new Music();
    boolean threadHasStarted = false;
    
    void playButon() {                                         
    	music.initialize();
        
    	if (threadHasStarted) {
    		synchronized(player) {
    			music.notify();
    			music.resumeSong();
    		}
    	}
        
    	else {
    		music.start();
    		threadHasStarted = true;
    	}
    }
    
    void pauseButton() {                                    
    	music.pauseSong();
    	synchronized(player) {
    		music.wait();
    	}
    }
    Last edited by carderne; 12-16-2008 at 04:08 PM.

  9. #9
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    8

    Default

    It can get pretty deep, try - if at all possible - to think of threads as two or three or four machines sitting side by side, running code that in some shape, form, or fashion needs to be sequenced in some controller like manner.

    Sounds like you are doing a music player.
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

  10. #10
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    I grasp the general concept of a 'thread;' not so much the actual Thread class.

    Astute observation. *wink

    I currently/primarily need help with the waiting and notifying etc...

  11. #11
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Ah, didn't realise you were using a 3rd party API. OK, having seen more clearly what you're doing, I think you need to:
    - forget about pausing inside the thread -- just have your thread sit and play, then exit
    - before playing, always register a PlayBackListener
    - you call stop() on the player (inside your pause button code), your PlayBackListener will be called with an event that you can query to ask it for the current position (as a "frame" number I think) -- when you do "resume", you'll need to start a new player to play from that start position
    - I am assuming that calling your player's stop() from the UI thread will stop will make the play() method return/throw an exception so that your thread can exit; if not, you'll have to play frame by frame (or portion at a time), checking the status of your 'please pause' variable in between sections. But hopefully it won't come to that.

  12. #12
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    Well I've followed your advice and made it so that pressing play creates a new object of the Music class, and that works perfectly.

    With the Listener I've had a bit of trouble.
    Here's my code:
    For the PlabackListener:
    Java Code:
    PlaybackListener listener = new PlaybackListener() {
    	public void songPaused(PlaybackEvent evt) {
    		saveFrame(evt);
    	}
    };
    And for the method it should call:
    Java Code:
    void saveFrame(PlaybackEvent evt) {
    	frame = evt.getFrame();//frame being a field
    }
    But this is never fired... i.e. saveFrame is never called...
    This is the first time I've manually used a Listener, so I could easily have done it very wrong...

    Thanks for your continued help. I'm learning a lot and it's really appreciated.

  13. #13
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

    Default

    Hehe. Not to worry about it after all, I got another package from the same people that does all of the threading and stuff by itself, which means I can just use their play(), pause() and resume() methods...

    Thanks for all of the help anyway, I've learnt quite a bit.

  14. #14
    carderne is offline Senior Member
    Join Date
    Nov 2007
    Posts
    160
    Rep Power
    8

Similar Threads

  1. Difference between Thread.yield() and Thread.sleep() methods
    By Nageswara Rao Mothukuri in forum New To Java
    Replies: 12
    Last Post: 07-30-2010, 06:37 PM
  2. passing a value from parent thread to child thread
    By sachinj13 in forum Threads and Synchronization
    Replies: 7
    Last Post: 09-07-2008, 10:06 PM
  3. data from the main/GUI thread to another runnin thread...
    By cornercuttin in forum Threads and Synchronization
    Replies: 2
    Last Post: 04-23-2008, 11:30 PM
  4. Replies: 0
    Last Post: 01-28-2008, 08:02 AM

Posting Permissions

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