簡體   English   中英

我正在用Java制作命令行音樂播放器,而“跳過”按鈕有時會跳過多次

[英]I'm making a command line music player in java, and my 'skip' button is sometimes skipping more than once

因此,基本上,我的代碼當前僅從commmand行接受一個參數,該行是所有wave文件將在播放列表中播放的文件夾。 我有另一個線程接受用戶輸入。 當用戶輸入“跳過”時,它將繼續通過項目的for循環。 一切正常,但是,如果我鍵入skip,然后按Enter,有時它會跳過兩次。 我認為這與線程業務有關。 這是我的代碼。

 package com.thechief.music;

 import java.io.File;
 import java.io.FilenameFilter;
 import java.util.Scanner;

 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
 import javax.sound.sampled.Clip;

 public class Player {

public static int index = 0; // The current clip playing
public static Clip[] clip;

public static void main(String[] args) throws Exception {
    Scanner scanner = new Scanner(System.in);

    FilenameFilter textFilter = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".wav");
        }
    };

    File[] files = new File(args[0]).listFiles(textFilter);
    clip = new Clip[files.length];

    Runnable b = new Runnable() {
        public void run() {
            while (true) {
                String command = scanner.next();
                if (command.equals("skip")) {
                    getCurrentClip().stop();
                } else if (command.equals("back")) {
                    getCurrentClip().stop();
                    if (index > 0) {
                        index -= 2;
                    } else {
                        System.out.println("Cannot go back further than the first item.");
                    }
                }
            }
        }
    };
    Thread second = new Thread(b);
    second.start();

    for (index = 0; index < clip.length; index++) {
        if (index < 0) index = 0;
        clip[index] = AudioSystem.getClip();
        if (index < 0) index = 0;
        AudioInputStream ais = AudioSystem.getAudioInputStream(files[index]);
        if (!getCurrentClip().isOpen()) {
            getCurrentClip().open(ais);
        } else {
            getCurrentClip().close();
            getCurrentClip().open(ais);
        }

        getCurrentClip().start();

        System.out.println("Now Playing: " + files[index].getName() + ", Time Left: "
                + (getCurrentClip().getMicrosecondLength() / 1000000.f) + " seconds.");

        while (getCurrentClip().getMicrosecondLength() != getCurrentClip().getMicrosecondPosition()
                || getCurrentClip().isActive()) {
            if (!getCurrentClip().isActive()) {
                break;
            }
        }
    }

    System.out.println("Playlist completed.");

    scanner.close();
    second.join();
}

public static Clip getCurrentClip() {
    return clip[index];
}
 }

這里:

public static int index = 0; // The current clip playing

該索引字段由多個線程使用和更新。 這意味着:任何事情都可能發生。

第一步:在這里使用AtomicInteger而不是int

當然,這是真正的答案:您必須研究自己在做什么。 只是在這里或那里添加new Thread().start()而不知道和了解自己在做什么,只是導致各種不可預測行為的秘訣。 這非常簡單:在多個線程之間共享可變數據時,您絕對必須確保采取必要的預防措施。

給出更多指導:防止類似if (index < 0) index = 0; 使種族

含義:例如,一個線程看到index = 1,然后將index變為0。但是,與此同時,另一個線程試圖讀取index,並且使用了錯誤的中間內容。

當您將該索引轉換為AtomicInteger ,可以開始執行以下操作:

synchronized(index) {
  if (index ...
    index = ...
}

例如。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM