I think I don't quite understand threading...

O

OscarC

Hi!

I'm building a slideshow app and I'd like to be able
to play some music while viewing the photos. So, I thought
in using two separate threads, one for the slideshow and
another for playing the music (I'm using javazoom.net's
MP3 libraries). Something like this:

Thread t1 = new Thread(new Slideshow(album));
t1.start();

Thread t2 = new Thread(new MP3Play());
t2.start();

The t1 thread opens a new undecorated JFrame and shows
the photos one after another. The t2 threads starts
playing some MP3 file.

Using this I'm not getting what I want. Now, the music
plays AFTER viewing the photos, not at the same time
which is the purpose of using threads. What am I doing
wrong ?

The code for the MP3Play class is:

public class MusicPlayer implements Runnable, BasicPlayerListener {

public void run() {

// Instantiate BasicPlayer.
BasicPlayer player = new BasicPlayer();
// BasicPlayer is a BasicController.
BasicController control = (BasicController) player;
// Register BasicPlayerTest to BasicPlayerListener events.
// It means that this object will be notified on BasicPlayer
// events such as : opened(...), progress(...), stateUpdated(...)
player.addBasicPlayerListener(this);

try { // Open file, or URL or Stream (shoutcast, icecast) to play.
control.open(new File("file.mp3"));

// control.open(new URL("http://yourshoutcastserver.com:8000"));
// Start playback in a thread. control.play();
// If you want to pause/resume/pause the played file then
// write a Swing player and just call control.pause(),
// control.resume() or control.stop().
// Use control.seek(bytesToSkip) to seek file
// (i.e. fast forward and rewind). seek feature will
// work only if underlying JavaSound SPI implements
// skip(...). True for MP3SPI (JavaZOOM) and SUN SPI's
// (WAVE, AU, AIFF).
// Set Volume (0 to 1.0). control.setGain(0.85);
// Set Pan (-1.0 to 1.0).
control.setPan(0.0);
control.play();
} catch (BasicPlayerException e) { e.printStackTrace(); }

}

public void stateUpdated(BasicPlayerEvent event) {
// Notification of BasicPlayer states (opened, playing, end of
media, ...)
System.out.println("stateUpdated : "+event.toString());
}

public void progress(int bytesread, long microseconds, byte[]
pcmdata, Map properties) {
// Pay attention to properties. It depends on underlying JavaSound SPI
// MP3SPI provides mp3.equalizer.
System.out.println("progress : "+properties.toString());
}

public void opened(Object stream, Map properties) {
// Pay attention to properties. It's useful to get duration,
// bitrate, channels, even tag such as ID3v2.
System.out.println("opened : "+properties.toString());
}

public void setController(BasicController controller) {
System.out.println("setController : "+controller);
}

}


Thanks in advance
 
B

Ben Wilson

Have you already tried lowering the priority of the Thread t1, and
sprinkling a couple of yield() calls around in your code?

A lot of the Thread functionality in Java is platform-dependent. Which
platform are you using?



OscarC said:
Hi!

I'm building a slideshow app and I'd like to be able
to play some music while viewing the photos. So, I thought
in using two separate threads, one for the slideshow and
another for playing the music (I'm using javazoom.net's
MP3 libraries). Something like this:

Thread t1 = new Thread(new Slideshow(album));
t1.start();

Thread t2 = new Thread(new MP3Play());
t2.start();

The t1 thread opens a new undecorated JFrame and shows
the photos one after another. The t2 threads starts
playing some MP3 file.

Using this I'm not getting what I want. Now, the music
plays AFTER viewing the photos, not at the same time
which is the purpose of using threads. What am I doing
wrong ?

The code for the MP3Play class is:

public class MusicPlayer implements Runnable, BasicPlayerListener {

public void run() {

// Instantiate BasicPlayer.
BasicPlayer player = new BasicPlayer();
// BasicPlayer is a BasicController.
BasicController control = (BasicController) player;
// Register BasicPlayerTest to BasicPlayerListener events.
// It means that this object will be notified on BasicPlayer
// events such as : opened(...), progress(...), stateUpdated(...)
player.addBasicPlayerListener(this);

try { // Open file, or URL or Stream (shoutcast, icecast) to play.
control.open(new File("file.mp3"));

// control.open(new URL("http://yourshoutcastserver.com:8000"));
// Start playback in a thread. control.play();
// If you want to pause/resume/pause the played file then
// write a Swing player and just call control.pause(),
// control.resume() or control.stop().
// Use control.seek(bytesToSkip) to seek file
// (i.e. fast forward and rewind). seek feature will
// work only if underlying JavaSound SPI implements
// skip(...). True for MP3SPI (JavaZOOM) and SUN SPI's
// (WAVE, AU, AIFF).
// Set Volume (0 to 1.0). control.setGain(0.85);
// Set Pan (-1.0 to 1.0).
control.setPan(0.0);
control.play();
} catch (BasicPlayerException e) { e.printStackTrace(); }

}

public void stateUpdated(BasicPlayerEvent event) {
// Notification of BasicPlayer states (opened, playing, end of
media, ...)
System.out.println("stateUpdated : "+event.toString());
}

public void progress(int bytesread, long microseconds, byte[]
pcmdata, Map properties) {
// Pay attention to properties. It depends on underlying JavaSound SPI
// MP3SPI provides mp3.equalizer.
System.out.println("progress : "+properties.toString());
}

public void opened(Object stream, Map properties) {
// Pay attention to properties. It's useful to get duration,
// bitrate, channels, even tag such as ID3v2.
System.out.println("opened : "+properties.toString());
}

public void setController(BasicController controller) {
System.out.println("setController : "+controller);
}

}


Thanks in advance
 
A

Abs

Ben said:
Have you already tried lowering the priority of the Thread t1, and
sprinkling a couple of yield() calls around in your code?

No, I haven't tried that. Thanks for the info.
A lot of the Thread functionality in Java is platform-dependent. Which
platform are you using?

I'm using winxp. But the app must work in Linux, too.
 
X

xarax

OscarC said:
Hi!

I'm building a slideshow app and I'd like to be able
to play some music while viewing the photos. So, I thought
in using two separate threads, one for the slideshow and
another for playing the music (I'm using javazoom.net's
MP3 libraries). Something like this:

Thread t1 = new Thread(new Slideshow(album));
t1.start();

Thread t2 = new Thread(new MP3Play());
t2.start();

The t1 thread opens a new undecorated JFrame and shows
the photos one after another. The t2 threads starts
playing some MP3 file.

Using this I'm not getting what I want. Now, the music
plays AFTER viewing the photos, not at the same time
which is the purpose of using threads. What am I doing
wrong ?
/snip/

There is apparently some synchronization issues
between the two threads, causing the second thread
to block until the first thread has completed its
work.

What is the behavior when you change the order
of starting the threads? Will the music play
and the pictures wait until the music is finished?
 
A

Abs

xarax said:
/snip/

There is apparently some synchronization issues
between the two threads, causing the second thread
to block until the first thread has completed its
work.

What is the behavior when you change the order
of starting the threads? Will the music play
and the pictures wait until the music is finished?

Yes, I've tried to reverse the starting order of
the threads with the same result, the music starts
after the slideshow.
 
X

xarax

Abs said:
Yes, I've tried to reverse the starting order of
the threads with the same result, the music starts
after the slideshow.

You're saying the interposing a Thread.sleep(10000) between
starting the MP3 player thread (1st thread) and the SlideShow
thread (2nd thread) won't play the music until after the
sleep() returns and starts the slide show thread and the
slide show thread finishes?

Thread t1 = new Thread(new MP3Play());
t1.start();
Thread.sleep(10000);
Thread t2 = new Thread(new Slideshow(album));
t2.start();

You will wait for the sleep(), then see the
entire slide show before the music starts?
 
A

Abs

xarax said:
You're saying the interposing a Thread.sleep(10000) between
starting the MP3 player thread (1st thread) and the SlideShow
thread (2nd thread) won't play the music until after the
sleep() returns and starts the slide show thread and the
slide show thread finishes?

Thread t1 = new Thread(new MP3Play());
t1.start();
Thread.sleep(10000);
Thread t2 = new Thread(new Slideshow(album));
t2.start();

You will wait for the sleep(), then see the
entire slide show before the music starts?

It seems it was a problem of thread priorities. I've reduced
the priority of the slideshow thread and now the 2 threads
start at the same time.


thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top