- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,在我更改 bgmPlaying 的值之前,这个 while 循环几乎什么也不做。效果很好。但是,如果我删除上面写着//testing的部分(没有任何换行符),它就不起作用。
这段代码实际上一直在检查音乐是否打开或关闭。
知道为什么当我删除 System.out.println() 部分时它会停止工作吗???
这是我的代码:
import java.io.File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
/**
* This class simply plays a background music in a seperate thread
* @author Mohammad Nafis
* @version 1.0
* @since 04-03-2018
*
*/
public class AudioPlayer implements Runnable{
/**
* this boolean indicates whether the background music is playing
*/
private boolean bgmPlaying = true;
public void stopBGM() {
bgmPlaying = false;
}
public void playBGM() {
bgmPlaying = true;
}
/**
* this is an overridden method from Runnable interface that executes when a thread starts
*/
@Override
public void run() {
try {
File soundFile = new File("sounds/epic_battle_music.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
clip.open(ais);
clip.loop(Clip.LOOP_CONTINUOUSLY);
//controlling the volume
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(-20);
clip.start();
while(true) {
if(bgmPlaying) {
gainControl.setValue(-20);
} else {
gainControl.setValue(-80);
}
while(bgmPlaying) {
//testing
System.out.println("BGM is on: ");
if(bgmPlaying == false) {
gainControl.setValue(-80);
break;
}
}
while(!bgmPlaying) {
//testing
System.out.println("BGM is off: ");
if(bgmPlaying == true) {
gainControl.setValue(-20);
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
此代码位于我的 Controller 类中,用于调用停止和播放方法。
//adding action listener
window.getpausebutton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
new Thread(new SoundEffect("sounds/clickSound.wav")).start();
bgm.stopBGM();
}
});
window.getplaybutton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
new Thread(new SoundEffect("sounds/clickSound.wav")).start();
bgm.playBGM();
}
});
最佳答案
使用 volatile
和Thread.sleep
实际上是解决该问题的方法,尽管它应该有效。但更大的问题是代码正忙于等待变量的状态发生变化,并且依赖于两个线程之间的共享状态。使用 volatile
或同步
您可以解决这些问题,但还有更好的方法。
在java.util.concurrent
包中,有一些用于处理并发的强大工具。相比之下,线程、 volatile 、 sleep (还有等待和通知)就像原始的手动工具。其中的强大工具之一是 BlockingQueue
及其各种实现,它可以让您实现类似 Actor Model 的东西。在Java中。
在 Actor 模型中,Actor 相互发送消息以执行操作,但他们从不共享内存。您可以定义一些简单的消息,例如“播放”、“静音”和“停止”,并将这些消息从控制线程发送到播放器线程。如果您使用 BlockingQueue,那么玩家看到消息不会有任何问题,并且不必忙于等待消息到达。它可以简单地尝试从队列中获取
一条消息,如果没有消息在等待,它就会阻塞,直到有消息可用为止。
以下是在代码中实现该功能的方法:
public enum Command {
PLAY, STOP, MUTE;
}
import java.io.File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import java.util.Objects;
import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* This class simply plays a background music in a separate thread
*
* @author Mohammad Nafis
* @version 1.0
* @since 04-03-2018
*/
public class AudioPlayer implements Runnable {
private final String filename;
private final BlockingQueue<Command> commandQueue =
new LinkedBlockingQueue<>();
public final static int LOUD = -20;
public final static int QUIET = -80;
public AudioPlayer(String filename) {
this.filename = Objects.requireNonNull(filename);
}
public void perform(Command command) throws InterruptedException {
commandQueue.put(Objects.requireNonNull(command));
}
@Override
public void run() {
try {
File soundFile = new File(filename);
AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
clip.open(ais);
clip.loop(Clip.LOOP_CONTINUOUSLY);
//controlling the volume
FloatControl gainControl = (FloatControl)
clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(LOUD);
clip.start();
forever: while (true) {
switch (commandQueue.take()) {
case PLAY:
gainControl.setValue(LOUD);
break;
case MUTE:
gainControl.setValue(QUIET);
break;
case STOP:
break forever;
}
}
clip.stop();
clip.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
AudioPlayer player = new AudioPlayer(args[0]);
Thread thread = new Thread(player);
thread.start();
Scanner in = new Scanner(System.in);
String cmd = "";
System.out.println("Type mute or play. Or stop to exit.");
do {
System.out.print(": ");
System.out.flush();
cmd = in.nextLine();
if ("play".equals(cmd)) player.perform(Command.PLAY);
else if ("mute".equals(cmd)) player.perform(Command.MUTE);
else if ("stop".equals(cmd)) player.perform(Command.STOP);
else System.out.println("I didn't understand that, sorry.");
} while (!"stop".equals(cmd));
player.perform(Command.STOP);
thread.join();
System.out.println("Be seeing you.");
}
}
一些注意事项:
clip.stop()
和 clip.close()
的调用,以便音频系统不会保留背景线程运行阻止程序退出。perform(Command)
方法虽然位于 AudioPlayer
类中,但将在调用它的控制线程上执行,但是没关系。由于队列是为并发而设计的,因此在控制线程上排队的命令将立即在播放器线程上可见。不需要Thread.sleep
。null
,AudioPlayer
构造函数和 perform
方法都会抛出异常。关于java - 当我删除 System.out.println 时,while 循环似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49890640/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!