簡體   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