Having fun with Threads
I am having troubles with Threading ;)
I have do开发者_如何学JAVAne an script about my class as follow:
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();
}
As you can see I have 2 Threads running, one which is getting network information and a second one which is cheking if the information from network has been received. The boolean variable mVarGlobal will be true, and then the Thread which is checking "CheckVarGlobal" will stop as the condition (!mVarGlobal) is false.
The problem is that once i get the information in the 1st Thread from network and speech the information, 2nd Thread still is running and speeching "something". I guess the 2nd Thread has not realize that CheckVarGlobal is true... I have typed the variable as volatile as it is used from 2 threads.
Any idea why is it happening, and how to solve it?
Thanks a lot,
Best. David.
Dayerman... Here is some EXPERIMENTAL code with two handlers.
Edit. I have edited the code to comply with best practices, using a switch in a single handler:
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);
}
Usage:
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();
}
};
Your are checking the variable in if condition rather than while condition.That means whenever it comes to thread 2 that time only it is checking.Better to use while condition in thread2.
精彩评论