我是 Java 多线程的新手。我已经进行了一些研究,阅读了教程并进行了测试,但是我遇到了这个问题。基本上,我正在设置游戏的骨架,并且我想要主活动类,一个包含方法的线程类,执行慢速操作(读取文件并将内容解压缩到缓冲区),并有一个线程是游戏循环对 UI 操作的反应。
首先,我有一个主活动类,它实例化并启动一个单独的线程:
public class ExperimentsActivity extends Activity {
// This is just a container class with some member data such as ByteBuffers and arrays
TestClass tclass = new TestClass(this);
// Main looping thread
MainLoopThread loop;
Thread mainLoop;
// Start the main looping thread which will trigger the engine's operations
loop = new MainLoopThread(tclass);
mainLoop = new Thread(loop);
mainLoop.start();
loop.setRunning(true);
(...)
}
然后,我有一个MainLoopThread
实现游戏逻辑线程的类:
public class MainLoopThread implements Runnable {
public boolean running;
private TestClass baseData;
// Thread for data loading/unpacking ( CLASS DEFINITION BELOW )
GFXUnpack dataUnpack;
Thread dataUnpackThread;
public MainLoopThread( TestClass testClassStructure ) {
running = false;
baseData = testClassStructure;
}
public void setRunning ( boolean run ) {
if ( run == true )
{
// Launch the thread which manages loading and unpacking graphics
dataUnpack = new GFXUnpack(baseData.filepack[0]);
dataUnpackThread = new Thread(dataUnpack);
dataUnpackThread.start();
dataUnpack.setRunning(true);
fileOpened = false;
// Open the GFX packet file
try {
synchronized (this) {
dataUnpack.setOperation(2);
Log.d("MainLoopThread", "File opening : waiting...");
while ( dataUnpack.fileOpened == false ) {
wait();
}
Log.d("MainLoopThread", "File opening wait completed");
}
if ( dataUnpack.outCode == -1 )
Log.d("MainLoopThread", "File opening error !!");
else fileOpened = true;
Log.d("MainLoopThread", "File opening completed");
}
catch ( Exception exp ) {
Log.d("MainLoopThread", "File opening code exception !!" + exp);
}
}
else if ( dataUnpack.running == true ) dataUnpack.setRunning(false); running = run;
}
// ------------------------------------
// Here is the main looping thread. All the events related to loading
// and unpacking graphics go here
public void run() {
while (running) {
synchronized (this) {
// ------ Read a GFX packet and update texture pixels
if ( fileOpened == true ) {
try {
// ( Do some stuff... )
wait();
} catch ( Exception exp ) {
Log.d("MainLoopThread", "Exception thrown !! " + exp );
}
}
} // ( Thread-out code removed. Anyway, it never passed here )
}
最后,GFXUnpack
包含在 SD 卡上打开文件的代码的线程类读取其中的内容并写入缓冲区:
public class GFXUnpack implements Runnable {
// -------------
public boolean running = false;
private Filedata fdata;
private int operation = 0, parameter = 0;
public boolean fileOpened;
public int outCode; // Used to signal the caller about the outcome of the operation
// ------------------------------
public GFXUnpack ( Filedata packetDataStructure ) {
this.fdata = packetDataStructure;
}
// --------
public void setRunning ( boolean run ) {
running = run; operation = 0; fileOpened = false;
outCode = 0; parameter = 0;
}
// --------
public void setOperation ( int op ) {
operation = op;
}
// ---
public void setOperation ( int op, int parm ) {
operation = op;
parameter = parm;
}
// ---------
public synchronized void run() {
while (running) {
try {
switch ( operation ) {
case ( 2 ) : // Open the gfx data file
( ...do stuff... )
break;
}
// ---------
try {
( ...Do some stuff here... )
Log.d("GFXUnpack", "Mapping file");
( ...Do some stuff here... )
Log.d("GFXUnpack", "Mapped file");
fileOpened = true;
outCode = 1;
} catch ( Exception e ) {
Log.d("GFXUnpack", "File opening exception !! " + e);
outCode = -1;
}
finally {
operation = 0; parameter = 0;
notifyAll();
Log.d("GFXUnpack", "Notified file opening");
}
}
break;
// ----------------
}
// ----- Other cases here...
} finally {
}
}
}
当我运行上面的,调试器输出是:
MainLoopThread File opening : waiting...
GFXUnpack 映射文件
GFXUnpack 映射文件
GFXUnpack 通知文件打开
然后,应用程序挂起,我必须强制关闭它。我想,因为我调用(在块中)notifyAll()
的run()
方法,调用者线程(MainLoopThread)会继续,我会看到调试器消息'文件打开完成',但应用程序挂起。GFXunpack
finally{}
有谁知道为什么会这样?