繁体   English   中英

如果乐器是同一子类的实例,则在 Java 中使用同步不允许它们一起演奏

[英]Using synchronization in Java to not allow musical instruments to play together if they're instances of the same sub-class

我创建了三个抽象类来划分乐器:String、Wind、Arc(其中每一个都扩展了 Thread 并指定了 run() 方法。我的乐器是这三个的子类。没有一个子类覆盖 run() 方法) . 我希望只有一种超类乐器(弦乐器、管乐器、弧形乐器)可以同时演奏。 不超过一个。 我怎样才能做到这一点?

重新编辑 09/02/2018 08:46 AM
谢谢@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;
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM