Java多线程声音崩溃
Posted
技术标签:
【中文标题】Java多线程声音崩溃【英文标题】:Java Multi-threaded sound crash 【发布时间】:2012-02-26 21:59:00 【问题描述】:我正在开发一个 Java 游戏项目,我需要能够同时实时播放多个声音。我已经实现了一个声音系统,可以生成新线程来播放 SourceDataLine 声音。
游戏在我的电脑上运行良好,但对于我的一位测试人员来说,音响系统会不时出现在他身上的崩溃。我们都在 Windows 7 上运行相同版本的 java (jre 1.6.0_29),经过几轮测试和谷歌搜索,我无法弄清楚为什么它总是对我很好,但崩溃了在他身上。
这是一个 SSCCE,演示了我的代码中出现问题的部分。重要的部分是 SoundPlayer、Sound 和 SoundThread 类。您需要在保存 SSCCE 的同一目录中包含两个名为 shortSound.wav 和 longSound.wav 的声音文件。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import java.util.HashMap;
import java.util.Collection;
import java.io.*;
import java.net.URL;
import java.util.LinkedList;
public class SoundSSCCE extends JFrame
private JPanel screenP;
private JPanel bgFraming;
/**
* Constructor
* Preconditions: None.
* Postconditions: The window for the SSCCE is created.
**/
public SoundSSCCE()
super("Sound problem SSCCE");
this.setSize(200,100);
// instantiate main window panel
screenP = new SSCCEPanel(this);
this.add(screenP);
// finishing touches on Game window
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
System.out.println("Game Window successfully created!!!");
public static void main(String[] args)
SoundSSCCE gui = new SoundSSCCE();
/**
* SSCCEPanel is the JPanel that manages the example's timer, painting, and logic.
**/
class SSCCEPanel extends JPanel
public Frame parentFrame;
private Timer timer;
public int logicLoops;
public double prevFPS;
boolean timerReady;
// The SoundPlayer object is used by the example to play the sounds.
public SoundPlayer soundPlayer;
public SSCCEPanel(Frame parent)
super(true);
parentFrame = parent;
this.setFocusable(true);
Toolkit.getDefaultToolkit().sync();
logicLoops = 0;
soundPlayer = new SoundPlayer();
TimerListener timerListener = new TimerListener();
prevFPS = 0;
timerReady = true;
timer = new Timer(0,timerListener);
this.setFPS(60);
timer.start();
/**
* setFPS()
* Preconditions: fps is a quantity of frames per second
* Postconditions: Sets the timer's refresh rate so that it
* fires fps times per second.
**/
public void setFPS(int fps)
int mspf = (int) (1000.0 /fps + 0.5);
timer.setDelay(mspf);
/**
* This is the JPanel's timer listener. It runs the example's logic and repaint
* methods each time it gets a timer signal.
**/
private class TimerListener implements ActionListener
long startTime = System.currentTimeMillis();
long lastTime = this.startTime;
int ticks = 0;
public void actionPerformed(ActionEvent e)
Object source = e.getSource();
if(source == timer)
// perform a loop through the game's logic and repaint.
synchronized(this)
if(timerReady)
timerReady = false;
runSSCCELogic();
repaint();
timerReady = true;
// Logic for Frames per Second counter
this.ticks++;
long currentTime = System.currentTimeMillis();
if(currentTime - startTime >= 500)
prevFPS = 1000.0 * ticks/(1.0*currentTime - startTime);
System.out.println(prevFPS);
startTime = currentTime;
ticks = 0;
lastTime = currentTime;
/**
* repaints the SSCCE.
* This just shows the current FPS and the number of sounds currently playing.
**/
public void paintComponent(Graphics g)
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
double roundedFPS = Math.round(prevFPS*10)/10.0;
g2D.setColor(new Color(0x000000));
g2D.drawString("FPS: " + roundedFPS, 20,20);
g2D.drawString("Sounds playing: " + soundPlayer.soundsPlaying(), 20,50);
g.dispose();
/**
* runSSCCEELogic()
* This is where the run-time logic for the SSCCE example is.
* All it will do is play sounds at regular narrowly-spaced intervals.
* The sounds are stored in the same directory as the SSCCE. Substitute any .wav
* file here in place of shortSound.wav and longerSound.wav.
**/
public void runSSCCELogic()
if(logicLoops % 4 == 0)
soundPlayer.play("shortSound.wav");
if(logicLoops% 40 == 0)
soundPlayer.play("longerSound.wav");
logicLoops++;
/**
* My game uses makes method calls to the SoundPlayer object whenever it
* needs to play any sounds. This separates the main game code from the lower-level
* mucking-about with Sound object code. It also makes it easier for me to make changes to
* my Sound class without having to make changes any lines in my game where I play sounds.
**/
class SoundPlayer
private HashMap<String,Sound> sounds;
private double volume;
private int soundsPlaying;
public SoundPlayer()
sounds = new HashMap<String,Sound>();
volume = 1.0;
soundsPlaying = 0;
/**
* playSound(String path)
* creates and plays a Sound specified by path.
* Preconditions: path is the file path for the sound.
* Postconditions: The sound is loaded and begins playing.
* This method returns a reference to that sound.
**/
public Sound play(String path)
Sound newSound;
if(volume == 0)
return null;
if(sounds.containsKey(path))
newSound = sounds.get(path);
else
newSound = new Sound(path);
sounds.put(path,newSound);
newSound.play(volume);
return newSound;
/**
* load(String path)
* preloads a sound to be play instances of at a later time
* Preconditions: path is the file path for the sound.
* Postconditions: The sound is loaded. This method returns
* a reference to that sound.
**/
public Sound load(String path)
Sound newSound;
if(sounds.containsKey(path))
newSound = sounds.get(path);
else
newSound = new Sound(path);
sounds.put(path,newSound);
return newSound;
public int soundsPlaying()
int count = 0;
Collection<Sound> soundsIterable = sounds.values();
for(Sound sound : soundsIterable)
count += sound.instances;
return count;
public int soundsLoaded()
return sounds.size();
public void setVolume(double vol)
this.volume = vol;
/**
* Sound objects store the path to a given sound file and spawn new threads
* to play instances of their sound when the SoundPlayer tells them to play.
**/
class Sound
public String path;
protected int instances;
protected URL soundURL;
public Sound(String name)
try
soundURL = getClass().getClassLoader().getResource(name);
instances = 0;
path = name;
catch(Exception ex)
System.out.println("An error occured while loading the sound file: " + name);
System.out.println(ex.getMessage());
ex.printStackTrace();
/**
* play(double volume)
* Preconditions: volume is between 0.0 and 1.0 inclusive, where 1.0 is
* at full volume and 0.0 is silent.
* Postconditions: The Sound spawns a new thread to play an instance
* of itself.
**/
public void play(double volume)
try
SoundThread clip = new SoundThread(this);
synchronized(this)
// increment the count of its instances. The SoundThread
// will automatically decrement the sound instance when it finishes.
instances++;
clip.setVolume(volume);
clip.start();
catch(Exception e)
System.out.println("Sound error: Error playing sound");
System.out.println(e.getMessage());
e.printStackTrace();
/**
* SoundThread is a thread that Sound objects spawn to play instances
* of their sounds. This supports multiple sounds being played simultaneously.
**/
class SoundThread extends Thread
public SourceDataLine clip;
public AudioInputStream stream;
private int bufferSize = 50;
private Sound parent;
public SoundThread(Sound parentSound)
try
parent = parentSound;
// obtains input stream from Audiosystem to read from the file.
stream = AudioSystem.getAudioInputStream(parentSound.soundURL);
AudioFormat format = stream.getFormat();
// obtains the sound file's line
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
// loads the line into the clip
clip = (SourceDataLine) AudioSystem.getLine(info);
// opens the clip onto the stream
clip.open(format);
System.out.println("Sound buffer size: " + clip.getBufferSize());
catch(Exception e)
System.out.println("error playing sound");
System.out.println(e.getMessage());
e.printStackTrace();
public void run()
try
// I start my sourceDataLine and begin reading data
// from the stream into its buffer.
clip.start();
int bytesRead = 0;
byte[] soundData = new byte[bufferSize];
// read data from the stream into the sourceDataLine until there
// is no more data to read
while(bytesRead != -1)
bytesRead = stream.read(soundData,0,bufferSize);
if(bytesRead >= 0)
clip.write(soundData, 0, bytesRead);
else
// Here I drain and close the line and its stream when
// the sound is finished playing (it has read all the bytes from its stream).
// My tester's log suggests that SourceDataLine.drain() is where it
// is crashing.
clip.drain();
clip.close();
stream.close();
// decrement the count of the Sound's instances.
synchronized(parent)
parent.instances--;
catch(Exception e)
System.out.println(e.getMessage());
e.printStackTrace();
public void setVolume(double vol)
try
FloatControl volCtrl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
if(vol > 1.0)
vol = 1.0;
if(vol < 0.0)
vol = 0.0;
// tricky, confusing sound math stuff.
float dB = (float) (Math.log(vol) / Math.log(10.0) * 20.0);
if(dB > volCtrl.getMaximum())
dB = volCtrl.getMaximum();
if(dB < volCtrl.getMinimum())
dB = volCtrl.getMinimum();
volCtrl.setValue(dB);
catch(Exception e)
System.out.println("set volume failed");
System.out.println(e.getMessage());
e.printStackTrace();
这是我的测试人员的 jre 在游戏崩溃时生成的日志文件。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=5212, tid=5524
#
# JRE version: 6.0_29-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.4-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C 0x0000000000000000
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- T H R E A D ---------------
Current thread (0x00000000097c4000): JavaThread "Thread-651" [_thread_in_native, id=5524, stack(0x000000000ecf0000,0x000000000edf0000)]
siginfo: ExceptionCode=0xc0000005, ExceptionInformation=0x0000000000000008 0x0000000000000000
Registers:
RAX=0x0000000000000000, RBX=0x00000000148ef5b0, RCX=0x00000000097c41d0, RDX=0x0000000000000002
RSP=0x000000000edef4f8, RBP=0x000000000edef6e0, RSI=0x00000000097c41d0, RDI=0x00000000097c41d0
R8 =0x000000000edef520, R9 =0x0000000000000000, R10=0x2b11000000000000, R11=0x0000000006146b00
R12=0x00000000148a1f00, R13=0x0000000000000000, R14=0x000000000edef710, R15=0x00000000097c4000
RIP=0x0000000000000000, EFLAGS=0x0000000000010246
Top of Stack: (sp=0x000000000edef4f8)
0x000000000edef4f8: 000000006d515842 000000000edef5a0
0x000000000edef508: 0000000000000000 000000000bfbbd18
0x000000000edef518: 000000006d525264 00000000148ef5b0
0x000000000edef528: 0000000006146b00 000000001491ddb0
0x000000000edef538: 2b11000000001f44 00000000096b0108
0x000000000edef548: 0000000000000000 000000006d90a5cb
0x000000000edef558: 000000006d511ed4 00000000097c41d0
0x000000000edef568: 000000006d511ed4 00000000148ef5b0
0x000000000edef578: 000000006d516055 0000000000000000
0x000000000edef588: 0000000000000000 0000000000000000
0x000000000edef598: 0000000000000000 00000000148ef5b0
0x000000000edef5a8: 0000000006146b00 000000001491ed56
0x000000000edef5b8: 2b11000000000000 00000000096b0108
0x000000000edef5c8: 0000000000000000 000000006d90a5cb
0x000000000edef5d8: 000000006d52b54b 00000000000005c8
0x000000000edef5e8: 00000000bc162e50 0000000000000000
Instructions: (pc=0x0000000000000000)
0xffffffffffffffe0:
Register to memory mapping:
RAX=0x0000000000000000 is an unknown value
RBX=0x00000000148ef5b0 is an unknown value
RCX=0x00000000097c41d0 is an unknown value
RDX=0x0000000000000002 is an unknown value
RSP=0x000000000edef4f8 is pointing into the stack for thread: 0x00000000097c4000
RBP=0x000000000edef6e0 is pointing into the stack for thread: 0x00000000097c4000
RSI=0x00000000097c41d0 is an unknown value
RDI=0x00000000097c41d0 is an unknown value
R8 =0x000000000edef520 is pointing into the stack for thread: 0x00000000097c4000
R9 =0x0000000000000000 is an unknown value
R10=0x2b11000000000000 is an unknown value
R11=0x0000000006146b00 is a global jni handle
R12=0x00000000148a1f00 is an unknown value
R13=0x0000000000000000 is an unknown value
R14=0x000000000edef710 is pointing into the stack for thread: 0x00000000097c4000
R15=0x00000000097c4000 is a thread
Stack: [0x000000000ecf0000,0x000000000edf0000], sp=0x000000000edef4f8, free space=1021k
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j com.sun.media.sound.MixerSourceLine.nDrain(J)V+0
j com.sun.media.sound.MixerSourceLine.drain()V+26
J gameEngine.SoundThread.run()V
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x0000000009959000 JavaThread "Thread-1843" [_thread_in_native, id=4748, stack(0x0000000015780000,0x0000000015880000)]
0x000000000995c000 JavaThread "Thread-1842" [_thread_in_native, id=10632, stack(0x00000000146b0000,0x00000000147b0000)]
0x0000000009959800 JavaThread "Thread-1841" [_thread_in_native, id=4240, stack(0x0000000015a80000,0x0000000015b80000)]
0x0000000009958800 JavaThread "Thread-1828" [_thread_blocked, id=632, stack(0x00000000145b0000,0x00000000146b0000)]
0x000000000995c800 JavaThread "Thread-1754" [_thread_in_native, id=11188, stack(0x0000000015980000,0x0000000015a80000)]
0x0000000009957800 JavaThread "Thread-1699" [_thread_in_native, id=8788, stack(0x00000000144b0000,0x00000000145b0000)]
0x000000000995a800 JavaThread "Thread-1650" [_thread_in_native, id=10860, stack(0x000000000fe20000,0x000000000ff20000)]
0x00000000097bc000 JavaThread "Java Sound Sequencer" [_thread_blocked, id=11096, stack(0x0000000006cc0000,0x0000000006dc0000)]
0x0000000009957000 JavaThread "Thread-1285" [_thread_in_native, id=10608, stack(0x00000000142b0000,0x00000000143b0000)]
0x00000000097c3800 JavaThread "Thread-1223" [_thread_in_native, id=6968, stack(0x000000000eff0000,0x000000000f0f0000)]
0x00000000097c9000 JavaThread "Thread-1157" [_thread_in_vm, id=9260, stack(0x00000000143b0000,0x00000000144b0000)]
0x00000000097c0800 JavaThread "Thread-1139" [_thread_in_native, id=10544, stack(0x00000000141b0000,0x00000000142b0000)]
0x00000000097ca800 JavaThread "Thread-1138" [_thread_in_native, id=8456, stack(0x00000000140b0000,0x00000000141b0000)]
0x00000000097c6800 JavaThread "Thread-1113" [_thread_in_native, id=10536, stack(0x000000000fa20000,0x000000000fb20000)]
0x00000000097c8800 JavaThread "Thread-1110" [_thread_in_native, id=7780, stack(0x000000000edf0000,0x000000000eef0000)]
0x00000000097c5800 JavaThread "Thread-1054" [_thread_in_native, id=10472, stack(0x000000000eef0000,0x000000000eff0000)]
0x00000000097c1800 JavaThread "Thread-1046" [_thread_in_native, id=6148, stack(0x0000000013fb0000,0x00000000140b0000)]
0x00000000097c0000 JavaThread "Thread-1030" [_thread_in_native, id=10720, stack(0x000000000e3a0000,0x000000000e4a0000)]
0x00000000097c8000 JavaThread "Thread-963" [_thread_in_native, id=3148, stack(0x000000000ac50000,0x000000000ad50000)]
0x00000000097c2000 JavaThread "Thread-923" [_thread_in_native, id=10492, stack(0x000000000fd20000,0x000000000fe20000)]
0x00000000097c7000 JavaThread "Thread-791" [_thread_in_native, id=2044, stack(0x000000000e5a0000,0x000000000e6a0000)]
0x00000000097c2800 JavaThread "Thread-751" [_thread_in_native, id=2780, stack(0x000000000e4a0000,0x000000000e5a0000)]
=>0x00000000097c4000 JavaThread "Thread-651" [_thread_in_native, id=5524, stack(0x000000000ecf0000,0x000000000edf0000)]
0x00000000097bf000 JavaThread "DestroyJavaVM" [_thread_blocked, id=10636, stack(0x0000000002370000,0x0000000002470000)]
0x00000000097be800 JavaThread "D3D Screen Updater" daemon [_thread_blocked, id=10044, stack(0x000000000d940000,0x000000000da40000)]
0x00000000097bd800 JavaThread "AWT-EventQueue-0" [_thread_blocked, id=3036, stack(0x000000000cc50000,0x000000000cd50000)]
0x00000000097bd000 JavaThread "AWT-Shutdown" [_thread_blocked, id=10372, stack(0x000000000cb50000,0x000000000cc50000)]
0x0000000009633800 JavaThread "TimerQueue" daemon [_thread_blocked, id=10840, stack(0x000000000b650000,0x000000000b750000)]
0x0000000009631000 JavaThread "Headspace mixer frame proc thread" daemon [_thread_blocked, id=10808, stack(0x000000000ae50000,0x000000000af50000)]
0x00000000095f0800 JavaThread "Java Sound Event Dispatcher" daemon [_thread_blocked, id=8628, stack(0x000000000a950000,0x000000000aa50000)]
0x00000000062c1000 JavaThread "Java Sound Event Dispatcher" daemon [_thread_blocked, id=10864, stack(0x000000000a850000,0x000000000a950000)]
0x000000000618c000 JavaThread "AWT-Windows" daemon [_thread_in_native, id=10984, stack(0x0000000006dc0000,0x0000000006ec0000)]
0x0000000006189800 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=1848, stack(0x0000000006bc0000,0x0000000006cc0000)]
0x0000000006145000 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=7160, stack(0x00000000066f0000,0x00000000067f0000)]
0x000000000052d800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=10604, stack(0x00000000065f0000,0x00000000066f0000)]
0x0000000000526800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2820, stack(0x00000000064f0000,0x00000000065f0000)]
0x0000000000524800 JavaThread "Attach Listener" daemon [_thread_blocked, id=1616, stack(0x00000000063f0000,0x00000000064f0000)]
0x0000000000523800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=9476, stack(0x00000000062f0000,0x00000000063f0000)]
0x000000000050f800 JavaThread "Finalizer" daemon [_thread_blocked, id=9472, stack(0x0000000005ff0000,0x00000000060f0000)]
0x0000000000506800 JavaThread "Reference Handler" daemon [_thread_blocked, id=8864, stack(0x0000000005ef0000,0x0000000005ff0000)]
Other Threads:
0x00000000004fe000 VMThread [stack: 0x0000000005df0000,0x0000000005ef0000] [id=3480]
0x0000000006160800 WatcherThread [stack: 0x00000000067f0000,0x00000000068f0000] [id=6728]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap
PSYoungGen total 10240K, used 4696K [0x00000000ead60000, 0x00000000eb980000, 0x0000000100000000)
eden space 10112K, 45% used [0x00000000ead60000,0x00000000eb1de278,0x00000000eb740000)
from space 128K, 75% used [0x00000000eb770000,0x00000000eb788000,0x00000000eb790000)
to space 1152K, 0% used [0x00000000eb860000,0x00000000eb860000,0x00000000eb980000)
PSOldGen total 43392K, used 23839K [0x00000000c0800000, 0x00000000c3260000, 0x00000000ead60000)
object space 43392K, 54% used [0x00000000c0800000,0x00000000c1f47f00,0x00000000c3260000)
PSPermGen total 21248K, used 12322K [0x00000000bb600000, 0x00000000bcac0000, 0x00000000c0800000)
object space 21248K, 57% used [0x00000000bb600000,0x00000000bc208830,0x00000000bcac0000)
Code Cache [0x0000000002470000, 0x00000000026f0000, 0x0000000005470000)
total_blobs=1022 nmethods=599 adapters=376 free_code_cache=47801344 largest_free_block=16000
Dynamic libraries:
0x0000000000400000 - 0x000000000042e000 C:\Windows\system32\java.exe
0x00000000774b0000 - 0x0000000077659000 C:\Windows\SYSTEM32\ntdll.dll
0x0000000077020000 - 0x000000007713f000 C:\Windows\system32\kernel32.dll
0x000007fefda00000 - 0x000007fefda6c000 C:\Windows\system32\KERNELBASE.dll
0x000007feff4e0000 - 0x000007feff5bb000 C:\Windows\system32\ADVAPI32.dll
0x000007feff6a0000 - 0x000007feff73f000 C:\Windows\system32\msvcrt.dll
0x000007fefe490000 - 0x000007fefe4af000 C:\Windows\SYSTEM32\sechost.dll
0x000007fefe4b0000 - 0x000007fefe5dd000 C:\Windows\system32\RPCRT4.dll
0x000000006d7f0000 - 0x000000006dfa8000 C:\Program Files\Java\jre6\bin\server\jvm.dll
0x0000000076dd0000 - 0x0000000076eca000 C:\Windows\system32\USER32.dll
0x000007feff740000 - 0x000007feff7a7000 C:\Windows\system32\GDI32.dll
0x000007fefde60000 - 0x000007fefde6e000 C:\Windows\system32\LPK.dll
0x000007fefdd10000 - 0x000007fefddd9000 C:\Windows\system32\USP10.dll
0x000007fefb970000 - 0x000007fefb9ab000 C:\Windows\system32\WINMM.dll
0x000007fefdce0000 - 0x000007fefdd0e000 C:\Windows\system32\IMM32.DLL
0x000007fefe5e0000 - 0x000007fefe6e9000 C:\Windows\system32\MSCTF.dll
0x000000006d760000 - 0x000000006d76e000 C:\Program Files\Java\jre6\bin\verify.dll
0x000000006d3b0000 - 0x000000006d3d7000 C:\Program Files\Java\jre6\bin\java.dll
0x000000006d7b0000 - 0x000000006d7c2000 C:\Program Files\Java\jre6\bin\zip.dll
0x000000006d000000 - 0x000000006d1c3000 C:\Program Files\Java\jre6\bin\awt.dll
0x000007fefb9b0000 - 0x000007fefba21000 C:\Windows\system32\WINSPOOL.DRV
0x000007fefdf80000 - 0x000007fefe183000 C:\Windows\system32\ole32.dll
0x000007fefe750000 - 0x000007feff4d8000 C:\Windows\system32\SHELL32.dll
0x000007fefdde0000 - 0x000007fefde51000 C:\Windows\system32\SHLWAPI.dll
0x000007fefc3b0000 - 0x000007fefc5a4000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_fa396087175ac9ac\COMCTL32.dll
0x000007fefbd70000 - 0x000007fefbd88000 C:\Windows\system32\DWMAPI.DLL
0x000007fefc1d0000 - 0x000007fefc226000 C:\Windows\system32\uxtheme.dll
0x000000006d2a0000 - 0x000000006d306000 C:\Program Files\Java\jre6\bin\fontmanager.dll
0x000007fefd840000 - 0x000007fefd84f000 C:\Windows\system32\CRYPTBASE.dll
0x000007feee310000 - 0x000007feee50f000 C:\Windows\system32\d3d9.dll
0x000007fefca70000 - 0x000007fefca7c000 C:\Windows\system32\VERSION.dll
0x000007fefbad0000 - 0x000007fefbad7000 C:\Windows\system32\d3d8thk.dll
0x000007feea170000 - 0x000007feeaabb000 C:\Windows\system32\nvd3dumx.dll
0x000007fefbb00000 - 0x000007fefbb2c000 C:\Windows\system32\powrprof.dll
0x000007fefe210000 - 0x000007fefe3e7000 C:\Windows\system32\SETUPAPI.dll
0x000007fefd9c0000 - 0x000007fefd9f6000 C:\Windows\system32\CFGMGR32.dll
0x000007feff5c0000 - 0x000007feff697000 C:\Windows\system32\OLEAUT32.dll
0x000007fefdcc0000 - 0x000007fefdcda000 C:\Windows\system32\DEVOBJ.dll
0x000000006d510000 - 0x000000006d53e000 C:\Program Files\Java\jre6\bin\jsound.dll
0x000007fefbd90000 - 0x000007fefbddb000 C:\Windows\system32\MMDevAPI.DLL
0x000007fefc230000 - 0x000007fefc35c000 C:\Windows\system32\PROPSYS.dll
0x000007fef3590000 - 0x000007fef35cb000 C:\Windows\system32\wdmaud.drv
0x0000000074b10000 - 0x0000000074b16000 C:\Windows\system32\ksuser.dll
0x000007fefbea0000 - 0x000007fefbea9000 C:\Windows\system32\AVRT.dll
0x000007fefb5c0000 - 0x000007fefb60f000 C:\Windows\system32\AUDIOSES.DLL
0x000007fef40f0000 - 0x000007fef40fa000 C:\Windows\system32\msacm32.drv
0x000007fef40d0000 - 0x000007fef40e8000 C:\Windows\system32\MSACM32.dll
0x000007fef3580000 - 0x000007fef3589000 C:\Windows\system32\midimap.dll
0x000007fefe3f0000 - 0x000007fefe489000 C:\Windows\system32\CLBCatQ.DLL
0x0000000010000000 - 0x0000000010065000 C:\Program Files\WIDCOMM\Bluetooth Software\btmmhook.dll
0x0000000077670000 - 0x0000000077677000 C:\Windows\system32\PSAPI.DLL
0x000000006d600000 - 0x000000006d617000 C:\Program Files\Java\jre6\bin\net.dll
0x000007fefdf30000 - 0x000007fefdf7d000 C:\Windows\system32\WS2_32.dll
0x000007feff7b0000 - 0x000007feff7b8000 C:\Windows\system32\NSI.dll
0x000007fefd140000 - 0x000007fefd195000 C:\Windows\system32\mswsock.dll
0x000007fefd130000 - 0x000007fefd137000 C:\Windows\System32\wship6.dll
0x000000006d620000 - 0x000000006d62b000 C:\Program Files\Java\jre6\bin\nio.dll
0x0000000009540000 - 0x0000000009571000 C:\Program Files\WIDCOMM\Bluetooth Software\btkeyind.dll
VM Arguments:
java_command: MyGameMain
Launcher Type: SUN_STANDARD
Environment Variables:
CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip
PATH=C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\PC Connectivity Solution\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Broadcom\Broadcom 802.11\Driver;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files\Java\jdk1.6.0_21\bin;C:\MinGW\bin;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Windows\system32\wbem;C:\Program Files (x86)\IVT Corporation\BlueSoleil\Mobile;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\Common Files\Microsoft Shared\Windows Live
USERNAME=***********
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 23 Stepping 6, GenuineIntel
--------------- S Y S T E M ---------------
OS: Windows 7 , 64 bit Build 7601 Service Pack 1
CPU:total 2 (2 cores per cpu, 1 threads per core) family 6 model 23 stepping 6, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1
Memory: 4k page, physical 4160724k(2268648k free), swap 8319600k(5448724k free)
vm_info: Java HotSpot(TM) 64-Bit Server VM (20.4-b02) for windows-amd64 JRE (1.6.0_29-b11), built on Oct 3 2011 01:06:42 by "java_re" with MS VC++ 8.0 (VS2005)
time: Sat Feb 04 09:25:56 2012
elapsed time: 145 seconds
日志文件表明,当声音完成并调用 SourceDataLine.drain() 以清除声音缓冲区中的任何剩余数据时,崩溃发生在声音线程期间。我不确定我做错了什么导致我的测试人员的 jre 在游戏中途崩溃......
您的声音/线程专家的任何见解都会有所帮助。
【问题讨论】:
有几个异常被捕获但未登录到 SoundThread。你确定这不是问题所在吗? 如需尽快获得更好的帮助,请发帖SSCCE。 Andrew:刚刚为它创建了一个 SSCCE。编辑了我的 OP 以提供它。 Jivings:我更改了那些 try-catch 块以打印异常消息。我正在等待我的测试人员查看异常(如果有)要说什么。 Jivings:我修改代码后,我的测试人员没有收到任何异常信息。它只是崩溃而不抛出异常。 【参考方案1】:可能为时已晚,无法为您提供任何帮助,但以防万一其他人感兴趣 -
在SoundThread::run
中,您正在检查bytesRead
,但如果stream.read
返回zero
(也许它不应该),那么您将陷入无限循环。
这可能取决于正在播放的声音的精确长度,并且可以解释为什么只有一个人能看到问题。
【讨论】:
【参考方案2】:冒着因为没有直接回答你的问题而被骂的风险,我想提出一个建议。可以创建一个自定义“剪辑”对象,该对象允许多次播放和以不同速度播放。如果 ClipTrack(我的名字)有多个光标,它们的输出可以相加并作为单个音频值发送出去。
我在这里演示了这样的用法: ClipTrack
该站点上有指向 Java 代码的链接,发布在 Java-Gaming.org,欢迎您使用。但是您可能需要大量编辑源代码。我知道我从最初发布它开始。我只是一名中级 Java 程序员,并且正在自学声音。有很多事情应该以不同的方式完成(对象将数据“移交”到我编写的混音器而不是直接播放它 - 但你可以重写它,如果完全不使用 CopyOnWriteArrayList 也可能不是最佳的-可以设计管理游标的阻塞方法)。
但是,至少在那里可以看到基本的想法。 :)
这种方法的潜在好处包括减少线程数。此外,您一次在内存中永远不会有超过一份原始音频数据的副本(而不是在所有剪辑中制作多个副本)。
我发现使用 javax.sound Clips 非常烦人,我很高兴不再纠结于它们。
【讨论】:
你好菲尔。最初,我使用 Clips 播放声音,但大约一半的测试我的游戏的人遇到了 Clips 问题,导致游戏延迟。如果我不能让任何其他工作,我会给你的 ClipTrack 课程一个机会。在花时间学习一个全新的类包之前,我想知道是什么导致我当前的声音线程代码崩溃。【参考方案3】:这是一个不同的答案,我不会修改之前关于编写自定义剪辑的建议(这是一种有效的方法,尽管方法非常不同)。
顺便说一句:我对 SourceDataLine 使用变量名“clip”感到困惑。真的应该重构那种东西!
好的。查看您的代码,您省略了我在播放重叠 SDL 的应用程序中包含的三个步骤。
line.drain();
line.stop();
line.close();
line = null;
aiStream.close();
aiStream = null;
其中“line”是 SourceDataLine,aiStream 是 AudioInputStream。
我认为将这些设置为 null 可能是关键步骤。不确定省略的 stop() 步骤有多重要。我无法确切告诉您为什么需要这样做,但它对我的应用程序产生了影响。
【讨论】:
我会让我的测试员试一试。 这并没有解决问题。 :( 我的测试人员说它仍然在崩溃。 感谢您告诉我。很抱歉,它没有帮助。【参考方案4】:此问题仍未解决。总之,问题可能是发生问题的机器所固有的,并且可能不值得在本机 Java 中进一步研究。
【讨论】:
以上是关于Java多线程声音崩溃的主要内容,如果未能解决你的问题,请参考以下文章