我是新的多線程與Java。我已經做了一些研究,閱讀教程,並完成測試,但我堅持這個問題。基本上,我設置了一個遊戲的骨架,我想要有主要的活動類,一個包含方法的線程類,執行緩慢的操作(讀取文件並將內容解包到緩衝區),並有一個線程是遊戲循環對UI操作做出反應。線程notall後notifyall()
首先,我有實例化和啓動一個單獨的線程的主要活動類:
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打開文件:等待...
GFXUnpack映射文件
GFXUnpack映射文件
GFXUnpack公告文件打開
然後,應用程序掛起,我不得不強行關閉它。我想,因爲我在方法GFXunpack
(finally{}
塊)中調用notifyAll()
方法,調用者線程(MainLoopThread)會繼續,我會看到調試器消息'File opening completed',但應用程序掛起。
有沒有人有任何想法,爲什麼發生這種情況?
謝謝JB,我會對你給我的方向做一些研究和測試! – Logicat