我制作了三个抽象类来划分乐器:弦乐,风,弧(每个乐器都扩展了Thread并指定了run()方法。我的乐器是这三个乐器的子类。没有一个子类可以覆盖run()方法) 。
我只想同时演奏一种超级乐器(弦乐,风,弧)。不超过一个。我怎样才能做到这一点?
重新编辑09/02/2018 08:46谢谢@miroh。但是我仍然有问题。在这里,我发布一个类和一个使用它的Main类。谁能说我该怎么解决?
阿奇课
package strumenti.archi;
import java.io.FileInputStream;
import java.io.InputStream;
import strumenti.Sound;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Archi extends Thread{
String soundFileName;
public Archi(String soundFileName){
this.soundFileName = soundFileName;
}
private static boolean canPlay = true;
private static Object playLock = new Object();
@Override
public void run() {
checkPlayable();
try {
// your code
play();
}
finally { // If a exception happens(or not) during the execution of the code block above, lock must be released.
synchronized (playLock) {
canPlay = true; // enable playing for others
playLock.notifyAll(); // wake up others
}
}
}
/*
* This is used to get the lock for the first one to come. Makes other ones wait.
*/
private static void checkPlayable() {
synchronized (playLock) {
while(!canPlay) {
try {
playLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
canPlay = false;
}
}
public synchronized void play(){
try {
InputStream in = new FileInputStream(soundFileName);
// create an audiostream from the inputstream
AudioStream audioStream = new AudioStream(in);
// play the audio clip with the audioplayer class
AudioPlayer.player.start(audioStream);
} catch (Exception ex) {
System.err.println("Cannot play sound.");
System.exit(0);
}
}
}
主班
package orchestra;
import strumenti.archi.*;
public class Orchestra {
public static synchronized void main(String[] args) {
Thread[] strumenti = new Thread[3];
strumenti[0] = new Archi("sample\\viola.wav");
strumenti[1] = new Archi("sample\\cello.wav");
strumenti[2] = new Archi("sample\\violino.wav");
for(Thread t:strumenti){
t.start();
}
//you should listen the three audio file one after the other
//but it doesn't work
}
}
问题解决了。线程必须等待,直到音频剪辑完成。
最佳答案
我没有看到您的代码,但是,如果我理解正确,则可以在这种情况下使用静态锁。下面的代码是针对单个乐器父级的。此代码使只有一个乐器的父乐器可以同时演奏,一个乐器演奏完后,正在等待的乐器将一个接一个地演奏。
private static boolean canPlay = true;
private static Object playLock = new Object();
@Override
public void run() {
checkPlayable();
try {
// your code
}
finally { // If a exception happens(or not) during the execution of the code block above, lock must be released.
synchronized (playLock) {
canPlay = true; // enable playing for others
playLock.notifyAll(); // wake up others
}
}
}
/*
* This is used to get the lock for the first one to come. Makes other ones wait.
*/
private static void checkPlayable() {
synchronized (playLock) {
while(!canPlay) {
try {
playLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
canPlay = false;
}
}
关于java - 如果它们是同一子类的实例,则在Java中使用同步不允许乐器一起演奏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48690103/