[英]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.