玩线程

时间:2011-02-23 11:47:53

标签: android multithreading

我遇到线程问题;)

我已经完成了关于我班级的剧本如下:

class Test{
TextToSpeech mTts = new TextToSpeech();
boolean volatile mVarGlobal = false;

class T1 extends Thread{
    public void run(){
        doSomething(){
            mVarGlobal = false;
            // network working...Take a while
            mTts.speak(...) //Speech information received from Network
            mVarGlobal = true;
        }
    } 
    T1 t = new T1();
    t.start();

class CheckVarGlobal extends Thread{
    public void run(){  
        if(!mVarGlobal) {
            text2Speech.speak("something");
        }
    postAtTime(this, 3000);
    } 
}
CheckVarGlobal c = new CheckVarGlobal ();
c.start();

}

正如您所看到的,我有两个正在运行的线程,一个正在获取网络信息,另一个正在收到来自网络的信息。布尔变量mVarGlobal将为true,然后检查“CheckVarGlobal”的Thread将在条件(!mVarGlobal)为false时停止。

问题是,一旦我从网络获取第一个帖子中的信息并发出信息,第二个线程仍然在运行并且正在说“某事”。我猜第二个线程没有意识到CheckVarGlobal是真的...我已经将变量键入为2个线程使用的volatile。

知道为什么会这样,以及如何解决它?

非常感谢,

最佳。 大卫。

2 个答案:

答案 0 :(得分:0)

你是在条件而不是条件的情况下检查变量。这意味着无论什么时候到线程2,只有它正在检查。更好地在thread2中使用条件。

答案 1 :(得分:0)

Dayerman ......这是一些带有两个处理程序的实验代码。

编辑。我已编辑代码以符合最佳实践,在单个处理程序中使用开关:

private Handler myHandler= new Handler(){
        @Override
        public void  handleMessage(Message msg){          
            switch(msg.what){
                case 0:
                    if (!isDoneThinking){
                        editTextConfusedText.setText("Still Thinking "+new Integer(thinkSeconds).toString());
                        thinkSeconds++;
                        this.removeMessages(0);
                        sendMessageDelayed(obtainMessage(0),1000);
                    }
                    else {
                        thinkSeconds= 0; // reset timer
                    }
                    break;
                case 1:
                    isDoneThinking= true;
                    onThreadedMessage(msg);
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    };
    public void onThreadMessage(Message msg){
        Bundle b= msg.getData();
        String encryptedText="";
        if (b != null){
            encryptedText= b.getString("encryptedText");
        }
        editTextConfusedText.setText(encryptedText);
        Log.d(TAG,encryptedText);
    }        

用法:

buttonConfuseText.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    final String inString= editTextPlainText.getText().toString();
                    isDoneThinking= false;
                    myHandler.sendEmptyMessage(0); // <=== START TIMER
                    Thread thread= new Thread( new Runnable() { // <== START THREADED RUNNABLE
                        public void run() {
                            String outString= encrypt(password,inString);
                            Message msg= myHandler.obtainMessage(1);
                            Bundle b= new Bundle();
                            b.putString("encryptedText",outString);
                            msg.setData(b);
                            myHandler.sendMessage(msg);
                            Log.d(TAG,outString);
                        }
                    });
                    thread.setDaemon(true);
                    thread.start();
                }
            };