Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * コルーチンもどき クラス
- * 派生してaction()をオーバーライドして使ってね。
- * @author F/T
- */
- package com.dokokano.shotchange.game.common;
- import android.util.Log; // for Log class
- public class Corouchan implements Runnable{
- Object lock_ = new Object();
- Object returnLock_ = new Object();
- Thread thread_;
- boolean exit_ = false;
- boolean exitDone_ = false;
- // スレッドスタート
- public void start() {
- Log.d("corouchan", "start()");
- thread_ = new Thread(this);
- thread_.start();
- // スレッドがスタートするまで待つ (returnLock_がnotifyされるのを待つ)
- synchronized (returnLock_) {
- try {
- returnLock_.wait(1000);
- } catch (InterruptedException e) {
- // run() 直後のreturnLock_.notifyAll();が早過ぎる場合はデッドロックになるかも。タイムオーバーで回避
- Log.d("corouchan", "InterruptedException@start");
- e.printStackTrace();
- }
- }
- }
- // スレッド終了 (終了要求を出す。即座には停止しない)
- // ※これ呼んでスレッド終了しないとアプリが終わらないよ!
- public void end() {
- Log.d("corouchan", "end()");
- exit_ = true;
- synchronized (lock_) {
- lock_.notifyAll();
- }
- }
- // 終了要求がきているか?
- public boolean isExit() {
- return exit_;
- }
- // 終了を完了したか?
- public boolean isExitDone() {
- return exitDone_;
- }
- @Override
- public void run() {
- Log.d("corouchan", "run()");
- // 開始処理
- // 呼び出し元のwaitを解除
- synchronized (returnLock_) {
- returnLock_.notifyAll();
- }
- // next()が呼ばれるまでwait
- synchronized (lock_) {
- try {
- lock_.wait();
- } catch (InterruptedException e) {
- Log.d("corouchan", "InterruptedException@run");
- e.printStackTrace();
- }
- }
- // コルーチン本体(ユーザー作成部)を呼ぶ
- action();
- // 終了処理
- exitDone_ = true;
- synchronized (returnLock_) {
- returnLock_.notifyAll();
- }
- }
- /**
- * ユーザーアクション
- * ここにコルーチンで実行したい処理を記述
- * yiedl() を呼ぶと呼び出し元に戻る
- */
- public void action() {
- Log.d("corouchan", "POS1");
- if ( yield() ) return;
- Log.d("corouchan", "POS2");
- if ( yield() ) return;
- Log.d("corouchan", "POS3");
- if ( yield() ) return;
- Log.d("corouchan", "POS4");
- if ( yield() ) return;
- Log.d("corouchan", "POS5");
- }
- // コルーチンの処理を一時停止して、呼び出し元に戻る
- public boolean yield() {
- Log.d("corouchan", "yield()");
- synchronized (returnLock_) {
- returnLock_.notifyAll();
- }
- try {
- synchronized (lock_) {
- lock_.wait(1000); // ※呼び出し元にもどった直後next()を呼ばれると、next()内のnotify()の後に、wait()が呼ばれてデッドロックになるかもしれない
- }
- } catch (InterruptedException e) {
- Log.d("corouchan", "InterruptedException@yield");
- e.printStackTrace();
- }
- Log.d("corouchan", "yield() - exit");
- return exit_;
- }
- // コルーチンの次の処理を実行
- // 戻り値: ture:成功 false:失敗(すでにコルーチンは終了しているなど)
- public boolean next() {
- Log.d("corouchan", "next()");
- if ( exit_ || exitDone_ ) return false; // すでに終了している
- try {
- synchronized (returnLock_) {
- synchronized (lock_) {
- lock_.notifyAll();
- }
- // コルーチン内で yield()が呼ばれるまでwait
- returnLock_.wait();
- }
- Log.d("corouchan", "next() - exit true");
- return true;
- } catch (InterruptedException e) {
- Log.d("corouchan", "InterruptedException@next");
- e.printStackTrace();
- }
- Log.d("corouchan", "next() - exit false");
- return false;
- }
- }
- /* サンプル
- Corouchan c = new Corouchan();
- c.start();
- for ( int i=0; i<10; i++ ) {
- c.next(); // next()を呼ぶとコルーチンに制御が戻る
- // i==4 の段階で「pos5」が出力され、以降はなにも起きない
- }
- c.end();
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement