Advertisement
fslasht

pseudo Coroutine in Java

Jul 2nd, 2011
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.81 KB | None | 0 0
  1. /**
  2.  * コルーチンもどき クラス
  3.  * 派生してaction()をオーバーライドして使ってね。
  4.  */
  5.  
  6.  
  7. import android.util.Log;
  8.  
  9. public class Corouchan implements Runnable{
  10.     Object lock_ = new Object();
  11.     Object returnLock_ = new Object();
  12.     Thread thread_;
  13.     boolean exit_ = false;
  14.     boolean exitDone_ = false;
  15.  
  16.     // スレッドスタート
  17.     public void start() {
  18.         thread_ = new Thread(this);
  19.         thread_.start();
  20.         synchronized (returnLock_) {
  21.             try {
  22. //              Thread.sleep(1000);
  23.                 returnLock_.wait();
  24.             } catch (InterruptedException e) {
  25.                 Log.d("corouchan", "InterruptedException@start");
  26.                 e.printStackTrace();
  27.             }
  28.  
  29.         }
  30.     }
  31.  
  32.     // スレッド終了 (終了要求を出す。即座には停止しない)
  33.     public void end() {
  34.         exit_ = true;
  35.         synchronized (lock_) {
  36.             lock_.notifyAll();
  37.         }
  38.     }
  39.  
  40.     // 終了要求がきているか?
  41.     public boolean isExit() {
  42.         return exit_;
  43.     }
  44.  
  45.     // 終了を完了したか?
  46.     public boolean isExitDone() {
  47.         return exitDone_;
  48.     }
  49.  
  50.     @Override
  51.     public void run() {
  52.         action();
  53.         exitDone_ = true;
  54.         synchronized (returnLock_) {
  55.             returnLock_.notifyAll();
  56.         }
  57.     }
  58.  
  59.     /**
  60.      * ユーザーアクション
  61.      * ここにコルーチンで実行したい処理を記述
  62.      * yiedl() を呼ぶと呼び出し元に戻る
  63.      */
  64.     public void action() {
  65.         Log.d("corouchan", "POS1");
  66.         if ( yield() ) return;
  67.         Log.d("corouchan", "POS2");
  68.         if ( yield() ) return;
  69.         Log.d("corouchan", "POS3");
  70.         if ( yield() ) return;
  71.         Log.d("corouchan", "POS4");
  72.         if ( yield() ) return;
  73.         Log.d("corouchan", "POS5");
  74.  
  75.     }
  76.  
  77.     // コルーチンの処理を一時停止して、呼び出し元に戻る
  78.     private boolean yield() {
  79.         synchronized (returnLock_) {
  80.             returnLock_.notifyAll();
  81.         }
  82.         try {
  83.             synchronized (lock_) {
  84.                 lock_.wait();
  85.             }
  86.         } catch (InterruptedException e) {
  87.             Log.d("corouchan", "InterruptedException@yield");
  88.             e.printStackTrace();
  89.         }
  90.         return exit_;
  91.     }
  92.  
  93.     // コルーチンの次の処理を実行
  94.     // 戻り値: ture:成功 false:失敗(すでにコルーチンは終了しているなど)
  95.     public boolean next() {
  96.         if ( exit_ || exitDone_ ) return false; // すでに終了している
  97.         synchronized (lock_) {
  98.             lock_.notifyAll();
  99.         }
  100.         try {
  101.             synchronized (returnLock_) {
  102.                 returnLock_.wait();
  103.             }
  104.             return true;
  105.         } catch (InterruptedException e) {
  106.             Log.d("corouchan", "InterruptedException@next");
  107.             e.printStackTrace();
  108.         }
  109.         return false;
  110.     }
  111.  
  112. }
  113.  
  114.  
  115.  
  116. /* サンプル
  117.     Corouchan c = new Corouchan();
  118.     c.start();          // この時点で「pos1」が出力される
  119.  
  120.     for ( int i=0; i<10; i++ ) {
  121.         c.next();       // next()を呼ぶとコルーチンに制御が戻る
  122.                         // i==3 の段階で「pos5」が出力され、以降はなにも起きない
  123.     }
  124.     c.end();
  125.  
  126. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement