やりたかったこと
外からキャンセルされない限り動き続けるスレッドにおいて、走り始めてから1秒以上たっても自スレッド内のフラグが立っていなかった場合、特別な動作をしたい。
Before
タイマータスクで1秒後にフラグを確認しに行く
- タイマースレッドもたつのでスレッドが乱立し何となくぐちゃぐちゃに
- フラグとかフィールドとか増えてくるといちいち排他処理とか考えなくてはならなくなってきて大変
public class AClass {
private AThread aThread=new AThread();
private volatile Handler mHandler;
public void start(){
aThread.start();
}
public void stop(){
aThread.mIsStopThread=true;
}
private class AThread extends Thread{
public volatile boolean mIsStopThread = false;
volatile private boolean mIsGot=false;
@Override
public void run() {
Timer mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
if ( !mIsGot&&!mIsStopThread) {
//1秒たってもほしいデータが取れてなくて、スレッドもキャンセルされてなかったら
}
}
});
}
}, 1000);
while (!mIsStopThread){
//外からスレッドをキャンセルされない限り動き続ける
//ほしいデータが取れたら、mIsGotフラグを立てる
}
}
}
}
After
タイマースレッドは立てずに、スレッドの走りはじめの時間を記録しておいて現在時刻との差分を見て1秒経っているか判断。
- これにより余分なスレッドを立てるのを防止してコードすっきり
public class AClass {
private AThread aThread=new AThread();
private volatile Handler mHandler;
public void start(){
aThread.start();
}
public void stop(){
aThread.mIsStopThread=true;
}
private class AThread extends Thread{
public volatile boolean mIsStopThread = false;
volatile private boolean mIsGot=false;
private long startTime;
@Override
public void run() {
super.run();
// RecordThreadの走りはじめの時間を記録
startTime = SystemClock.elapsedRealtime();
while (!mIsStopThread){
if (!mIsGot && (SystemClock.elapsedRealtime() - startTime) > 1000) {
//1秒たってもほしいデータが取れてなくて、スレッドもキャンセルされてなかったら
}
//外からスレッドをキャンセルされない限り動き続ける
//ほしいデータが取れたら、mIsGotフラグを立てる
if(!mIsGot){
//もしまだとれてなかったらいったん寝かす
try {
Thread.sleep(100);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
}