root/as3/Thread/trunk/src/org/libspark/thread/Thread.as

リビジョン 3371, 53.2 kB (コミッタ: yossy, コミット時期: 2 年 前)

Thread: 割り込みハンドラがすぐに実行されるように修正 (see #104, #117)

Line 
1 /*
2  * ActionScript Thread Library
3  *
4  * Licensed under the MIT License
5  *
6  * Copyright (c) 2008 BeInteractive! (www.be-interactive.org) and
7  *                    Spark project  (www.libspark.org)
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25  * THE SOFTWARE.
26  *
27  */
28 package org.libspark.thread
29 {
30         import flash.events.Event;
31         import flash.events.IEventDispatcher;
32         import flash.utils.Dictionary;
33         import flash.utils.getQualifiedClassName;
34         import flash.utils.getQualifiedSuperclassName;
35         import flash.utils.getDefinitionByName;
36         import org.libspark.thread.errors.CurrentThreadNotFoundError;
37         import org.libspark.thread.errors.IllegalThreadStateError;
38         import org.libspark.thread.errors.InterruptedError;
39         import org.libspark.thread.errors.ThreadLibraryNotInitializedError;
40        
41         /**
42          * Thread クラスは ActionScript Thread Library 1.0 (そうめん) の核となるクラスで、擬似スレッドを実現します.
43          *
44          * <p>ここで実現される擬似スレッドは、タスクシステムと Java のスレッドモデルをベースとしています。
45          * 処理をいくつかのメソッドに切り分け、呼び出すメソッド (「<em>実行関数</em>」と呼びます) を切り替えつつ
46          * 順々に実行していくことで、処理を進めます。</p>
47          *
48          * <p>新しいスレッドを作成するためには、まず Thread クラスのサブクラスを作成します。
49          * このサブクラスは、 Thread クラスの run メソッドをオーバーライドする必要があります。
50          * たとえば、「Hello, Thread!!」と出力するスレッドは、次のようになります。</p>
51          * <listing>public class HelloThread extends Thread
52          * {
53          *     override protected function run():void
54          *     {
55          *         trace('Hello, Thread!!');
56          *     }
57          * }</listing>
58          *
59          * <p>作成したスレッドを実行するためには、 Thread Library を初期化する必要があります。
60          * 次のように、 Thread クラスの静的メソッド initialize を呼び出すことで初期化を行います。
61          * このとき、引数に IThreadExecutor インターフェイスの実装クラスのインスタンスを指定します。
62          * この IThreadExecutor インスタンスは、「いつスレッドを実行するか」を決める重要な役割を担っています。
63          * ここでは、 EnterFrameThreadExecutor クラスのインスタンスを渡し、フレーム実行のタイミングで
64          * スレッドが実行されるようにしています。初期化処理は、アプリケーションの最初で一度だけ行えば、その後呼び出す必要はありません。</p>
65          * <listing>Thread.initialize(new EnterFrameThreadExecutor());</listing>
66          *
67          * <p>最後に、次のように HelloThread クラスのインスタンスを作り、 start メソッドを呼び出すことで、
68          * スレッドの実行を開始します。</p>
69          * <listing>var t:Thread = new HelloThread();
70          * t.start();</listing>
71          *
72          * <p>スレッドは親子関係を形成します。この親子関係は、スレッドの実行開始時に決定されます。
73          * スレッドの start を呼び出したスレッド (つまりカレントスレッド) は、親スレッドとなり、
74          * start が呼び出されたスレッドは、その親スレッドの子スレッドとなります。
75          * ただし、 start の呼び出しがスレッドの外 (つまりカレントスレッドが null のとき) に行われた場合、
76          * start が呼び出されたスレッドはトップレベルスレッドとなります。</p>
77          *
78          * <p>スレッドの親子関係は、スレッドの実行順序と例外の伝播において重要になります。
79          * スレッドの実行は、一番最初に開始されたトップレベルスレッドから始まります。今、このスレッドを A と呼ぶことにします。
80          * A に子スレッドがいる場合、 A の実行よりも先にまず、子スレッドが、開始された順番で実行されます。
81          * この子スレッドが実行されるとき、その子スレッドにさらに子スレッド (Aから見て孫スレッド) がいる場合、
82          * その子スレッドの実行より先に孫スレッドが開始された順番で実行され、これが子スレッドがいなくなるまで続けられます。
83          * 全ての A の子スレッドの実行が終了すると、 A が実行され、次に、A の次に開始されたトップレベルスレッドの実行が
84          * 同様にして続きます。</p>
85          *
86          * <p>スレッド内で例外が発生し、その例外が、例外が発生したスレッド内で捕捉されなかった場合、
87          * 例外は親スレッドに伝播します。例外が発生したのがトップレベルスレッドで、親スレッドがいない場合、
88          * 例外は uncaughtErrorHandler に渡されます。</p>
89          *
90          * <p>子スレッドよりも先に親スレッドが終了した場合、その親スレッドの全ての子スレッドは孤児スレッドとなり、
91          * トップレベルスレッドとして再配置されます。</p>
92          *
93          * <p>スレッドはある時点で、以下のいずれかの状態を取ります。これらの値は ThreadState クラスで定義されており、
94          * state プロパティを通して知ることができます。</p>
95          * <ul>
96          * <li>NEW</li>
97          * <li>RUNNABLE</li>
98          * <li>WAITING</li>
99          * <li>TIMED_WAITING</li>
100          * <li>TERMINATING</li>
101          * <li>TERMINATED</li>
102          * </ul>
103          *
104          * <p>スレッドが生成されると、まずはじめに状態は「NEW」に設定されます。この後、 start メソッドによって
105          * スレッドが開始されると、状態は「RUNNABLE」に設定されます。「NEW」以外の状態のスレッドを start メソッドによって
106          * 開始することはできません。</p>
107          *
108          * <p>wait メソッド、 join メソッド等の呼び出しによってスレッドが待機状態になる場合、状態は「WAITING」に
109          * 設定されます。このとき、タイムアウトが設定されるか、sleep メソッドの呼び出しである場合、状態は「TIMED_WAITING」に
110          * 設定されます。待機状態が解除されると状態は元に戻ります。</p>
111          *
112          * <p>スレッドが終了フェーズに移行すると、状態は「TERMINATING」に設定されます。スレッドが終了フェーズから
113          * 実行フェーズに戻ることは無く、同様に状態が「TERMINATING」から「RUNNABLE」に戻ることもありません。
114          * 終了フェーズが終わり、完全にスレッドが終了すると、状態は「TERMINATED」に設定されます。</p>
115          *
116          * <p>スレッドの動作を視覚的に知りたい場合、以下の動作チャートを見ることをお勧めします。</p>
117          * <ul>
118          * <li>http://www.libspark.org/htdocs/as3/thread-files/behavior-chart.png</li>
119          * </ul>
120          *
121          * @author      yossy:beinteractive
122          * @see #run()
123          * @see #initialize()
124          * @see #start()
125          * @see #uncaughtErrorHandler()
126          * @see #state
127          * @see ThreadState
128          * @see http://www.libspark.org/htdocs/as3/thread-files/behavior-chart.png
129          */
130         public class Thread extends Monitor
131         {
132                 private static var _executor:IThreadExecutor;
133                 private static var _threadIndex:uint = 0;
134                 private static var _currentThread:Thread = null;
135                 private static var _toplevelThreads:Array = [];
136                 private static var _uncaughtErrorHandler:Function = null;
137                 private static var _defaultErrorHandlers:Dictionary = null;
138                
139                 /**
140                  * スレッドライブラリを初期化します.
141                  *
142                  * <p>このメソッドは、最初に一度だけ呼び出してください。</p>
143                  *
144                  * <p>スレッドの実行は、指定された IThreadExecutor インスタンスによって行われます。
145                  * (このメソッド内で、 IThreadExectuor#start が呼び出されます)</p>
146                  *
147                  * @param       executor        スレッドの実行を行う IThreadExecutor
148                  * @see IThreadExecutor
149                  */
150                 public static function initialize(executor:IThreadExecutor):void
151                 {
152                         _threadIndex = 0;
153                         _currentThread = null;
154                         _toplevelThreads.length = 0;
155                        
156                         // 古い IThreadExecutor の実行を止める
157                         if (_executor != null) {
158                                 _executor.stop();
159                         }
160                        
161                         _executor = executor;
162                        
163                         // 新しい IThreadExecutor の実行を開始
164                         if (_executor != null) {
165                                 _executor.start();
166                         }
167                 }
168                
169                 /**
170                  * initialize メソッドの呼び出しによって IThreadExecutor が設定され、スレッドが実行可能な状態であれば true、そうでなければ false を返します.
171                  *
172                  * @see #initialize()
173                  */
174                 public static function get isReady():Boolean
175                 {
176                         return _executor != null;
177                 }
178                
179                 /**
180                  * 現在実行中のスレッドを返します.
181                  *
182                  * <p>現在実行中のスレッドがない場合、 null を返します。</p>
183                  */
184                 public static function get currentThread():Thread
185                 {
186                         return _currentThread;
187                 }
188                
189                 /**
190                  * 現在実行中のスレッドを返します.
191                  *
192                  * <p>ただし、現在実行中のスレッドがない(currentThread が null)の場合は CurrentThreadNotFoundError をスローします。</p>
193                  *
194                  * @return      現在実行中のスレッド
195                  * @throws      org.libspark.thread.errors.CurrentThreadNotFoundError   現在実行中のスレッドがない場合
196                  * @private
197                  */
198                 internal static function getCurrentThread():Thread
199                 {
200                         var t:Thread = currentThread;
201                        
202                         if (t != null) {
203                                 return t;
204                         }
205                        
206                         throw new CurrentThreadNotFoundError('Expected Thread.currentThread is not null, but actual null.');
207                 }
208                
209                 /**
210                  * どのスレッドにも捕捉されなかった例外のためのハンドラを設定します.
211                  *
212                  * <p>スレッド内で例外が発生し、処理されないままトップレベルまで到達するとこのハンドラが呼び出されます。</p>
213                  *
214                  * <p>ここに登録する関数は、第一引数に発生した例外である Object と、第二引数に発生元のスレッドである Thread を引数としてとる必要があります。</p>
215                  */
216                 public static function get uncaughtErrorHandler():Function
217                 {
218                         return _uncaughtErrorHandler;
219                 }
220                
221                 /**
222                  * @private
223                  */
224                 public static function set uncaughtErrorHandler(value:Function):void
225                 {
226                         _uncaughtErrorHandler = value;
227                 }
228                
229                 /**
230                  * 例外ハンドラを取得します.
231                  *
232                  * <p>ただし、ユーザーによって例外ハンドラが設定されていない場合、デフォルトのハンドラを返します。</p>
233                  *
234                  * @return      ユーザーによって設定された例外ハンドラ。無い場合はデフォルトのハンドラ。
235                  * @private
236                  */
237                 private static function getUncaughtErrorHandler():Function
238                 {
239                         return uncaughtErrorHandler || defaultErrorHandler;
240                 }
241                
242                 /**
243                  * 例外ハンドラのデフォルトの実装です.
244                  *
245                  * <p>このハンドラでは、例外の内容及び発生元の Thread の文字列表現を出力します。</p>
246                  *
247                  * @param       e       発生した例外
248                  * @param       t       例外が発生したスレッド
249                  */
250                 public static function defaultErrorHandler(e:Object, t:Thread):void
251                 {
252                         trace((t ? t.toString() + ' ' : '') + (e is Error ? (e as Error).getStackTrace() : e.toString()));
253                 }
254                
255                 /**
256                  * 現在実行中のスレッドおよびその子スレッドで例外が発生した場合で、error メソッドによるハンドラの指定がなされていない場合にデフォルトで実行する実行関数を設定します.
257                  *
258                  * <p>ここで設定される実行関数は、発生した例外である Object と、例外が発生したスレッドである Thread のふたつの引数をとる関数である必要があります。</p>
259                  *
260                  * <p>この関数によって例外を処理できた (この関数内で再び例外が発生しなかった) 場合で、この関数内で
261                  * next メソッドによる実行関数の設定が行われなかった場合、例外が発生する前の実行関数の設定を復元します。</p>
262                  *
263                  * @param       klass   どの型の例外が発生した場合に関数を実行するかを示すクラス
264                  * @param       func    例外が発生した際に実行される実行関数
265                  * @param       autoTermination 実行関数の実行後、Thread#next(null) を自動的に呼び出すのであれば true, そうでなければ false
266                  */
267                 public static function registerDefaultErrorHandler(klass:Class, func:Function, autoTermination:Boolean = false):void
268                 {
269                         if (func != null) {
270                                 addDefaultErrorHandler(klass, func, autoTermination);
271                         }
272                         else {
273                                 removeDefaultErrorHandler(klass);
274                         }
275                 }
276                
277                 /**
278                  * デフォルトエラーハンドラマップを返します.
279                  *
280                  * @return      デフォルトエラーハンドラマップ
281                  * @private
282                  */
283                 private static function getDefaultErrorHandlers():Dictionary
284                 {
285                         return _defaultErrorHandlers || (_defaultErrorHandlers = new Dictionary());
286                 }
287                
288                 /**
289                  * デフォルトエラーハンドラをデフォルトエラーハンドラマップに追加します.
290                  *
291                  * @param       klass   エラークラス
292                  * @param       handler エラーハンドラ
293                  * @param       reset   リセットするか
294                  * @param       autoTermination 自動で next(null) を呼び出すか
295                  * @private
296                  */
297                 private static function addDefaultErrorHandler(klass:Class, handler:Function, autoTermination:Boolean):void
298                 {
299                         getDefaultErrorHandlers()[getQualifiedClassName(klass)] = new ErrorHandler(handler, false, autoTermination);
300                 }
301                
302                 /**
303                  * デフォルトエラーハンドラをデフォルトエラーハンドラマップから削除します.
304                  *
305                  * @param       klass   エラークラス
306                  * @private
307                  */
308                 private static function removeDefaultErrorHandler(klass:Class):void
309                 {
310                         // ハンドラマップが存在しなければ何もしない
311                         if (_defaultErrorHandlers == null) {
312                                 return;
313                         }
314                        
315                         // ハンドラマップから削除
316                         delete _defaultErrorHandlers[getQualifiedClassName(klass)];
317                 }
318                
319                 /**
320                  * 全てのスレッドを実行します.
321                  *
322                  * <p>通常、このメソッドは IThreadExector インターフェイスの実装クラスによって呼び出されます。</p>
323                  */
324                 public static function executeAllThreads():void
325                 {
326                         // 全てのトップレベルスレッドを呼び出す
327                         var threads:Array = _toplevelThreads;
328                         var l:uint = threads.length;
329                         for (var i:uint = 0; i < l;) {
330                                 var thread:Thread = Thread(threads[i]);
331                                 if (!thread.execute()) {
332                                         // スレッドが終了した場合は削除
333                                         threads.splice(i, 1);
334                                         --l;
335                                 }
336                                 else {
337                                         ++i;
338                                 }
339                                 // 伝播すべき例外が発生している場合はキャッチされない例外ハンドラを呼び出す
340                                 // Note: _errorThread が null の場合、この例外はまだ伝播すべきではないことを示す
341                                 if (thread._error != null && thread._errorThread != null) {
342                                         try {
343                                                 getUncaughtErrorHandler()(thread._error, thread._errorThread);
344                                         }
345                                         catch (e:Object) {
346                                                 defaultErrorHandler(e, null);
347                                         }
348                                         thread._error = null;
349                                         thread._errorThread = null;
350                                 }
351                         }
352                 }
353                
354                 /**
355                  * 指定されたスレッドをトップレベルスレッドとして追加します.
356                  *
357                  * @param       thread  追加するスレッド
358                  * @private
359                  */
360                 private static function addToplevelThread(thread:Thread):void
361                 {
362                         _toplevelThreads.push(thread);
363                 }
364                
365                 /**
366                  * 指定されたスレッドをトップレベルスレッドとして追加します.
367                  *
368                  * @param       threads 追加するスレッドの配列
369                  * @private
370                  */
371                 private static function addToplevelThreads(threads:Array):void
372                 {
373                         _toplevelThreads.push.apply(_toplevelThreads, threads);
374                 }
375                
376                 /**
377                  * 現在実行中のスレッドが次に実行する実行関数を設定します.
378                  *
379                  * <p>この設定は、スレッドの実行のたびにリセットされます。</p>
380                  *
381                  * <p>このメソッドの呼び出しによって次に実行する実行関数が設定されない場合、スレッドは終了フェーズへと移行します。</p>
382                  *
383                  * @param       func    次に実行する実行関数
384                  */
385                 public static function next(func:Function):void
386                 {
387                         getCurrentThread()._runHandler = func;
388                 }
389                
390                 /**
391                  * 現在実行中のスレッドおよびその子スレッドで例外が発生した場合に実行する実行関数を設定します.
392                  *
393                  * <p>ここで設定される実行関数は、発生した例外である Object と、例外が発生したスレッドである Thread のふたつの引数をとる関数である必要があります。</p>
394                  *
395                  * <p>この関数によって例外を処理できた (この関数内で再び例外が発生しなかった) 場合で、この関数内で
396                  * next メソッドによる実行関数の設定が行われなかった場合、例外が発生する前の実行関数の設定を復元します。</p>
397                  *
398                  * <p>この設定は、reset 引数が false に設定されない限り、スレッドの実行のたびにリセットされます。</p>
399                  *
400                  * @param       klass   どの型の例外が発生した場合に関数を実行するかを示すクラス
401                  * @param       func    例外が発生した際に実行される実行関数
402                  * @param       reset   次の実行のタイミングでこの設定を削除する場合には true、そうでなければ false
403                  * @param       autoTermination 実行関数の実行後、Thread#next(null) を自動的に呼び出すのであれば true, そうでなければ false
404                  */
405                 public static function error(klass:Class, func:Function, reset:Boolean = true, autoTermination:Boolean = false):void
406                 {
407                         if (func != null) {
408                                 getCurrentThread().addErrorHandler(klass, func, reset, autoTermination);
409                         }
410                         else {
411                                 getCurrentThread().removeErrorHandler(klass);
412                         }
413                 }
414                
415                 /**
416                  * 現在実行中のスレッドが待機中にタイムアウトした場合に実行する実行関数を設定します.
417                  *
418                  * <p>この設定は、スレッドの実行のたびにリセットされます。</p>
419                  *
420                  * @param       func    タイムアウトした場合に実行する実行関数
421                  */
422                 public static function timeout(func:Function):void
423                 {
424                         getCurrentThread()._timeoutHandler = func;
425                 }
426                
427                 /**
428                  * 現在実行中のスレッドが指定されたイベントが発生した場合に実行する実行関数を設定します.
429                  *
430                  * <p>ここで設定される実行関数は、発生したイベントである Event を引数にとる関数である必要があります。</p>
431                  *
432                  * <p>このメソッドによってイベントハンドラが設定される場合、スレッドは自動的にイベントが発生するまで待機状態となります。
433                  * ただし、 next メソッドによって次に実行する実行関数が設定される場合、待機状態にはならず、実行が継続されます。</p>
434                  *
435                  * <p>この設定は、スレッドの実行のたびにリセットされます。</p>
436                  *
437                  * @param       dispatcher      イベントリスナーの登録先となるディスパッチャ
438                  * @param       type    捕捉するイベント名
439                  * @param       func    イベントが発生した場合に実行する実行関数
440                  * @param       useCapture      flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。
441                  * @param       priority        flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。
442                  * @param       useWeakReference        flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。
443                  * @see flash.events.IEventDispatcher#addEventListener()
444                  */
445                 public static function event(dispatcher:IEventDispatcher, type:String, func:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
446                 {
447                         getCurrentThread().addEventHandler(dispatcher, type, func, useCapture, priority, useWeakReference);
448                 }
449                
450                 /**
451                  * 現在実行中のスレッドの実行を、指定された時間だけ中断させます.
452                  *
453                  * <p>指定された時間が経過すると、 sleep メソッドが呼び出されなかった場合と同様に実行が再開されます。</p>
454                  *
455                  * <p>スレッドの実行が中断しても、子スレッドの実行が中断されることはありません。</p>
456                  *
457                  * @param       time    実行を中断させる時間 (ミリ秒)
458                  */
459                 public static function sleep(time:uint):void
460                 {
461                         // time が 0 だと永遠に待ってしまうので最低でも 1 にする
462                         if (time == 0) {
463                                 time = 1;
464                         }
465                        
466                         // カレントスレッドを取得
467                         var current:Thread = getCurrentThread();
468                        
469                         // sleep 用のモニタがなければ生成
470                         if (current._sleepMonitor == null) {
471                                 current._sleepMonitor = new Monitor();
472                         }
473                        
474                         // sleep 用のモニタを使って wait をかけて指定時間眠らせる
475                         current._sleepMonitor.wait(time);
476                 }
477                
478                 /**
479                  * 現在実行中のスレッドが待機中に割り込まれた場合に実行する実行関数を設定します.
480                  *
481                  * <p>このメソッドによって割り込みハンドラが設定されていない状態で、待機中に割り込みが発生すると、
482                  * 例外 InterruptedError が発生します。</p>
483                  *
484                  * <p>この設定はスレッドの実行のたびにリセットされます。</p>
485                  *
486                  * @param       func    待機中に割り込まれた場合に実行する実行関数
487                  */
488                 public static function interrupted(func:Function):void
489                 {
490                         getCurrentThread()._interruptedHandler = func;
491                 }
492                
493                 /**
494                  * 現在のスレッドが割り込まれているかどうかを調べます.
495                  *
496                  * <p>このメソッドによりスレッドの「割り込みステータス」がクリアされます。
497                  * つまり、このメソッドが続けて2回呼び出された場合、2回目の呼び出しは false を返します。</p>
498                  *
499                  * @return      現在のスレッドが割り込まれている場合は true、そうでない場合は false
500                  */
501                 public static function checkInterrupted():Boolean
502                 {
503                         // カレントスレッドを取得
504                         var current:Thread = getCurrentThread();
505                        
506                         // 割り込みステータスを取得
507                         var status:Boolean = current._isInterrupted;
508                        
509                         // ステータスが設定されている場合はクリア
510                         if (status) {
511                                 current._isInterrupted = false;
512                         }
513                        
514                         // ステータスを返す
515                         return status;
516                 }
517                
518                 /**
519                  * 新しい Thread クラスのインスタンスを生成します.
520                  */
521                 public function Thread()
522                 {
523                         _id = ++_threadIndex;
524                         _name = 'Thread' + _id;
525                         _state = ThreadState.NEW;
526                         _runningState = ThreadState.NEW;
527                         _children = null;
528                         _runHandler = null;
529                         _savedRunHandler = null;
530                         _timeoutHandler = null;
531                         _interruptedHandler = null;
532                         _waitMonitor = null;
533                         _joinMonitor = null;
534                         _sleepMonitor = null;
535                         _eventMonitor = null;
536                         _event = null;
537                         _errorHandlers = null;
538                         _error = null;
539                         _errorThread = null;
540                         _eventHandlers = null;
541                         _isInterrupted = false;
542                 }
543                
544                 private var _id:uint;
545                 private var _name:String;
546                 private var _state:uint;
547                 private var _runningState:uint;
548                 private var _children:Array;
549                 private var _runHandler:Function;
550                 private var _savedRunHandler:Function;
551                 private var _timeoutHandler:Function;
552                 private var _interruptedHandler:Function;
553                 private var _waitMonitor:IMonitor;
554                 private var _joinMonitor:IMonitor;
555                 private var _sleepMonitor:IMonitor;
556                 private var _eventMonitor:IMonitor;
557                 private var _event:Event;
558                 private var _errorHandlers:Dictionary;
559                 private var _error:Object;
560                 private var _errorThread:Thread;
561                 private var _eventHandlers:Array;
562                 private var _isInterrupted:Boolean;
563                
564                 /**
565                  * このスレッドのユニークな識別子を返します.
566                  *
567                  * <p>initialize メソッドが呼び出されない限り、ふたつのスレッドに同じ id が割り振られることはありません。</p>
568                  */
569                 public function get id():uint
570                 {
571                         return _id;
572                 }
573                
574                 /**
575                  * このスレッドの名前を設定します.
576                  */
577                 public function get name():String
578                 {
579                         return _name;
580                 }
581                
582                 /**
583                  * @private
584                  */
585                 public function set name(value:String):void
586                 {
587                         _name = value;
588                 }
589                
590                 /**
591                  * このスレッドのクラス名を返します.
592                  *
593                  * <p>デフォルトでは、 getQualifiedClassName メソッドを使用してクラス名を取得します。</p>
594                  */
595                 public function get className():String
596                 {
597                         var names:Array = getQualifiedClassName(this).split(/::/);
598                         return names.length == 2 ? names[1] : names[0];
599                 }
600                
601                 /**
602                  * このスレッドの状態を返します.
603                  *
604                  * <p>返される値は、 ThreadState クラスで定義されている定数のいずれかになります。</p>
605                  *
606                  * @see ThreadState
607                  */
608                 public function get state():uint
609                 {
610                         return _state;
611                 }
612                
613                 /**
614                  * このスレッドが割り込まれている場合は true、そうでない場合は false を返します.
615                  *
616                  * <p>このプロパティが true を返すようになるのは、待機状態<em>でない</em>スレッドに対して、
617                  * interrupt メソッドで割り込んだ場合です。</p>
618                  *
619                  * @see #interrupt()
620                  */
621                 public function get isInterrupted():Boolean
622                 {
623                         return _isInterrupted;
624                 }
625                
626                 /**
627                  * スレッドを開始します.
628                  *
629                  * <p>スレッドが既に開始されている場合 (state が NEW でない場合) は IllegalThreadStateError が
630                  * スローされます。</p>
631                  *
632                  * <p>スレッドライブラリが初期化されていない状態の場合 (isReady が false の場合) は ThreadLibraryNotInitializedError が
633                  * スローされます。</p>
634                  *
635                  * <p>あるスレッドの実行中にこのメソッドが呼び出された場合、そのスレッドはこのメソッドが呼び出されたスレッドの親スレッドとなり、
636                  * このメソッドが呼び出されたスレッドは子スレッドとなります。</p>
637                  *
638                  * <p>スレッドが実行中で無い場合にこのメソッドが呼び出された場合、このメソッドが呼び出されたスレッドはトップレベルスレッドとなります。</p>
639                  *
640                  * <p>このメソッドが呼び出されると、実行関数はまず run メソッドに設定されます。</p>
641                  *
642                  * @throws      org.libspark.thread.errors.IllegalThreadStateError      スレッドが既に開始されている場合
643                  * @throws      org.libspark.thread.errors.ThreadLibraryNotInitializedError     スレッドライブラリが初期化されていない場合
644                  */
645                 public function start():void
646                 {
647                         // 初期化されていなければエラー
648                         if (!isReady) {
649                                 throw new ThreadLibraryNotInitializedError('Thread Library is not initialized. Please call Thread#initialize before.');
650                         }
651                        
652                         // 既に実行されていたらエラー
653                         if (_state != ThreadState.NEW) {
654                                 throw new IllegalThreadStateError('Thread is already running.');
655                         }
656                        
657                         // state を実行フェーズに切り替える
658                         _state = ThreadState.RUNNABLE;
659                         _runningState = ThreadState.RUNNABLE;
660                        
661                         // 次の実行関数を run に設定
662                         _runHandler = run;
663                        
664                         // カレントスレッドを取得
665                         var current:Thread = currentThread;
666                        
667                         if (current != null) {
668                                 // カレントスレッドがある(=別のスレッド内で start された)場合はそのスレッドの子となる
669                                 current.addChildThread(this);
670                         }
671                         else {
672                                 // カレントスレッドがない場合はトップレベルスレッドとなる
673                                 addToplevelThread(this);
674                         }
675                 }
676                
677                 /**
678                  * このスレッドを待機状態に移行させます.
679                  *
680                  * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p>
681                  *
682                  * @param       timeout タイムアウト付かどうか
683                  * @param       monitor 待機先のモニタ
684                  * @private
685                  */
686                 internal function monitorWait(timeout:Boolean, monitor:IMonitor):void
687                 {
688                         // wait できる状態でなければエラー
689                         if ((_state != ThreadState.RUNNABLE && _state != ThreadState.TERMINATING) || _waitMonitor != null) {
690                                 throw new IllegalThreadStateError('Thread can not wait.');
691                         }
692                        
693                         // state を待機状態に切り替える
694                         _state = timeout ? ThreadState.TIMED_WAITING : ThreadState.WAITING;
695                        
696                         // モニタを保存
697                         _waitMonitor = monitor;
698                 }
699                
700                 /**
701                  * このスレッドを待機状態から復帰させます.
702                  *
703                  * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p>
704                  *
705                  * @param       monitor 待機先のモニタ
706                  * @private
707                  */
708                 internal function monitorWakeup(monitor:IMonitor):void
709                 {
710                         // 待機状態でなければエラー
711                         if ((_state != ThreadState.WAITING && _state != ThreadState.TIMED_WAITING) || _waitMonitor != monitor) {
712                                 throw new IllegalThreadStateError('Thread can not wakeup.');
713                         }
714                        
715                         // state を実行状態に切り替える
716                         _state = _runningState;
717                        
718                         // 保存されていたモニタを破棄
719                         _waitMonitor = null;
720                 }
721                
722                 /**
723                  * このスレッドを待機状態からタイムアウトさせます.
724                  *
725                  * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p>
726                  *
727                  * @param       monitor 待機先のモニタ
728                  * @private
729                  */
730                 internal function monitorTimeout(monitor:IMonitor):void
731                 {
732                         // 待機時間付の待機状態でなければエラー
733                         if (_state != ThreadState.TIMED_WAITING || _waitMonitor != monitor) {
734                                 throw new IllegalThreadStateError('Thread can not wakeup.');
735                         }
736                        
737                         // state を実行状態に切り替える
738                         _state = _runningState;
739                        
740                         // sleep によるタイムアウトではない場合
741                         if (_waitMonitor != _sleepMonitor) {
742                                 // 次に実行する実行関数をタイムアウト用のものに切り替える
743                                 if (_timeoutHandler != null) {
744                                         _runHandler = _timeoutHandler;
745                                 }
746                         }
747                        
748                         // 保存されていたモニタを破棄
749                         _waitMonitor = null;
750                 }
751                
752                 /**
753                  * join 用のモニタを返します.
754                  *
755                  * @return      join 用のモニタ
756                  * @private
757                  */
758                 private function getJoinMonitor():IMonitor
759                 {
760                         return _joinMonitor || (_joinMonitor = new Monitor());
761                 }
762                
763                 /**
764                  * このスレッドが終了するまで、現在のスレッドを待機させます.
765                  *
766                  * @param       timeout 待機させる時間 (ミリ秒)。 0 を指定した場合、永遠に待ち続けます
767                  * @return      待機する必要がある場合は true、そうでない場合は false
768                  */
769                 public function join(timeout:uint = 0):Boolean
770                 {
771                         // 既に終了していたらそのまま帰る
772                         if (_state == ThreadState.TERMINATED) {
773                                 return false;
774                         }
775                        
776                         // join 用のモニタで wait する
777                         getJoinMonitor().wait(timeout);
778                        
779                         return true;
780                 }
781                
782                 /**
783                  * このスレッドに割り込みます.
784                  *
785                  * <p>このスレッドが待機中である場合、割り込みステータスはクリアされ、スレッドが起床します。
786                  * このとき、割り込みハンドラが設定されていれば実行関数を割り込みハンドラに設定して実行を再開し、
787                  * そうでない場合は InterruptedError を発生させます。</p>
788                  *
789                  * <p>待機中でない場合、このスレッドの割り込みステータスが設定されます。</p>
790                  */
791                 public function interrupt():void
792                 {
793                         if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) {
794                                 // 待機中の場合
795                                 // モニタに対して待機セットから抜けることを伝える
796                                 _waitMonitor.leave(this);
797                                 _waitMonitor = null;
798                                 // state を切り替える
799                                 _state = _runningState;
800                                
801                                 // 割り込みハンドラがあれば
802                                 if (_interruptedHandler != null) {
803                                        
804                                         // 実行関数を割り込みハンドラに設定
805                                         _runHandler = _interruptedHandler;
806                                        
807                                         // 入れ子になる場合があるのでカレントスレッドを保存
808                                         var current:Thread = _currentThread;
809                                        
810                                         try {
811                                                 // そしてすぐ実行してみる
812                                                 internalExecute(null, this);
813                                         }
814                                         finally {
815                                                 // カレントスレッドを復元
816                                                 _currentThread = current;
817                                         }
818                                 }
819                                 else {
820                                         // 割り込みハンドラがなければ例外を発生
821                                         _error = new InterruptedError();
822                                 }
823                         }
824                         else {
825                                 // そうでない場合は割り込みステータスを設定
826                                 _isInterrupted = true;
827                         }
828                 }
829                
830                 /**
831                  * 子スレッドの配列を返します.
832                  *
833                  * @return      子スレッドの配列
834                  * @private
835                  */
836                 private function getChildren():Array
837                 {
838                         return _children || (_children = []);
839                 }
840                
841                 /**
842                  * 子スレッドを子スレッドの配列に追加します.
843                  *
844                  * @param       thread  追加する子スレッド
845                  * @private
846                  */
847                 private function addChildThread(thread:Thread):void
848                 {
849                         getChildren().push(thread);
850                 }
851                
852                 /**
853                  * エラーハンドラマップを返します.
854                  *
855                  * @return      エラーハンドラマップ
856                  * @private
857                  */
858                 private function getErrorHandlers():Dictionary
859                 {
860                         return _errorHandlers || (_errorHandlers = new Dictionary());
861                 }
862                
863                 /**
864                  * エラーハンドラをエラーハンドラマップに追加します.
865                  *
866                  * @param       klass   エラークラス
867                  * @param       handler エラーハンドラ
868                  * @param       reset   リセットするか
869                  * @param       autoTermination 自動で next(null) を呼び出すか
870                  * @private
871                  */
872                 private function addErrorHandler(klass:Class, handler:Function, reset:Boolean, autoTermination:Boolean):void
873                 {
874                         getErrorHandlers()[getQualifiedClassName(klass)] = new ErrorHandler(handler, reset, autoTermination);
875                 }
876                
877                 /**
878                  * エラーハンドラをエラーハンドラマップから削除します.
879                  *
880                  * @param       klass   エラークラス
881                  * @private
882                  */
883                 private function removeErrorHandler(klass:Class):void
884                 {
885                         // ハンドラマップが存在しなければ何もしない
886                         if (_errorHandlers == null) {
887                                 return;
888                         }
889                        
890                         // ハンドラマップから削除
891                         delete _errorHandlers[getQualifiedClassName(klass)];
892                 }
893                
894                 /**
895                  * エラーハンドラマップをリセットします.
896                  *
897                  * @private
898                  */
899                 private function resetErrorHandlers():void
900                 {
901                         // ハンドラマップが存在しなければ何もしない
902                         if (_errorHandlers == null) {
903                                 return;
904                         }
905                        
906                         // 登録されているハンドラを巡回
907                         for (var key:String in _errorHandlers) {
908                                 // reset が true であればハンドラを削除する
909                                 if (ErrorHandler(_errorHandlers[key]).reset) {
910                                         delete _errorHandlers[key];
911                                 }
912                         }
913                 }
914                
915                 /**
916                  * 指定されたエラーに該当するエラーハンドラを返します.
917                  *
918                  * <p>エラーハンドラが見つからず、デフォルトのエラーハンドラが登録されている場合、それを返します。</p>
919                  *
920                  * @param       error   エラー
921                  * @return      該当するエラーハンドラ。無ければ null
922                  * @private
923                  */
924                 private function getErrorHandler(error:Object):ErrorHandler
925                 {
926                         // まずスレッド自身に登録されているエラーハンドラを検索
927                         var handler:ErrorHandler = getErrorHandlerFrom(error, _errorHandlers);
928                         // 見つからなければ、デフォルトのエラーハンドラを検索
929                         if (handler == null) {
930                                 handler = getErrorHandlerFrom(error, _defaultErrorHandlers);
931                         }
932                         return handler;
933                 }
934                
935                 /**
936                  * 指定されたエラーに該当するエラーハンドラを指定されたハンドラマップから返します.
937                  *
938                  * @param       error   エラー
939                  * @param       handlers        ハンドラの検索先となるハンドラマップ
940                  * @return      該当するエラーハンドラ。無ければ null
941                  */
942                 private function getErrorHandlerFrom(error:Object, handlers:Dictionary):ErrorHandler
943                 {
944                         // ハンドラマップが存在しなければ null を返す
945                         if (handlers == null) {
946                                 return null;
947                         }
948                        
949                         // error のクラス名を取得
950                         var className:String = getQualifiedClassName(error);
951                        
952                         // クラス名が取得できる限り回す
953                         while (className != null) {
954                                 // ハンドラマップからクラス名をキーにしてハンドラを検索する
955                                 var handler:ErrorHandler = handlers[className];
956                                 // 見つかればそれを返す
957                                 if (handler != null) {
958                                         return handler;
959                                 }
960                                 // 見つからなければ、スーパークラスを辿る
961                                 try {
962                                         className = getQualifiedSuperclassName(getDefinitionByName(className));
963                                 }
964                                 catch (e:ReferenceError) {
965                                         // ここで出る ReferenceError は getDefinitionByName によるもの
966                                         // プライベートクラス等の場合に起こりうる
967                                         className = null;
968                                 }
969                         }
970                        
971                         return null;
972                 }
973                
974                 /**
975                  * イベント待機用のモニタを返します.
976                  *
977                  * @return      イベント待機用のモニタ
978                  * @private
979                  */
980                 private function getEventMonitor():IMonitor
981                 {
982                         return _eventMonitor || (_eventMonitor = new Monitor());
983                 }
984                
985                 /**
986                  * イベントハンドラの配列を返します.
987                  *
988                  * @return      イベントハンドラの配列
989                  * @private
990                  */
991                 private function getEventHandlers():Array
992                 {
993                         return _eventHandlers || (_eventHandlers = []);
994                 }
995                
996                 /**
997                  * イベントハンドラをイベントハンドラの配列に追加します.
998                  *
999                  * @param       dispatcher      ディスパッチャ
1000                  * @param       type    イベントタイプ
1001                  * @param       func    イベントハンドラ
1002                  * @param       useCapture      addEventListener 参照
1003                  * @param       priority        addEventListener 参照
1004                  * @param       useWeakReference        addEventListener 参照
1005                  * @private
1006                  */
1007                 private function addEventHandler(dispatcher:IEventDispatcher, type:String, func:Function, useCapture:Boolean, priority:int, useWeakReference:Boolean):void
1008                 {
1009                         // イベントハンドラを作成してリストに追加
1010                         getEventHandlers().push(new EventHandler(dispatcher, type, eventHandler, func, useCapture, priority, useWeakReference));
1011                 }
1012                
1013                 /**
1014                  * イベントハンドラの配列をリセットします.
1015                  *
1016                  * @private
1017                  */
1018                 private function resetEventHandlers():void
1019                 {
1020                         // イベントハンドラリストがなければ何もしない
1021                         if (_eventHandlers == null) {
1022                                 return;
1023                         }
1024                        
1025                         // 全てのイベントハンドラの登録を解除
1026                         for each (var handler:EventHandler in _eventHandlers) {
1027                                 handler.unregister();
1028                         }
1029                        
1030                         // 配列を初期化
1031                         _eventHandlers.length = 0;
1032                 }
1033                
1034                 /**
1035                  * イベントが発生した際に実行されるハンドラです.
1036                  *
1037                  * @param       e       発生したイベント
1038                  * @param       handler 該当するイベントハンドラ
1039                  * @private
1040                  */
1041                 private function eventHandler(e:Event, handler:EventHandler):void
1042                 {
1043                         // 既にイベントが起こっていれば何もしない
1044                         if (_event != null) {
1045                                 return;
1046                         }
1047                        
1048                         // イベントを保存
1049                         _event = e;
1050                        
1051                         // 該当するイベントハンドラを次の実行関数に設定
1052                         _runHandler = handler.func;
1053                        
1054                         // イベントハンドラをリセット
1055                         resetEventHandlers();
1056                        
1057                         // 待機状態である場合
1058                         if (_waitMonitor != null) {
1059                                 // モニタに対して待機セットから抜けることを伝える
1060                                 _waitMonitor.leave(this);
1061                                 // 保存されていたモニタを破棄
1062                                 _waitMonitor = null;
1063                         }
1064                        
1065                         // state を実行状態に切り替える
1066                         _state = _runningState;
1067                        
1068                         // 入れ子になる場合があるのでカレントスレッドを保存
1069                         var current:Thread = _currentThread;
1070                        
1071                         try {
1072                                 // そしてすぐ実行してみる
1073                                 internalExecute(null, this);
1074                         }
1075                         finally {
1076                                 // カレントスレッドを復元
1077                                 _currentThread = current;
1078                         }
1079                 }
1080                
1081                 /**
1082                  * 子スレッドを含め、このスレッドを実行します.
1083                  *
1084                  * @return      このスレッドの実行が継続していれば true、そうでなければ (実行が終了したら) false
1085                  * @private
1086                  */
1087                 private function execute():Boolean
1088                 {
1089                         // まだ start していなければ何もしない
1090                         if (_state == ThreadState.NEW) {
1091                                 return true;
1092                         }
1093                         // 既に終了していれば何もしない
1094                         if (_state == ThreadState.TERMINATED) {
1095                                 return false;
1096                         }
1097                        
1098                         // 発生した例外
1099                         var error:Object = _error;
1100                         var errorThread:Thread = _errorThread || this;
1101                        
1102                         // すべての子スレッドを呼び出す
1103                         var children:Array = _children;
1104                         if (children != null) {
1105                                 var cl:uint = children.length;
1106                                 for (var ci:uint = 0; ci < cl; ) {
1107                                         var child:Thread = Thread(children[ci]);
1108                                         if (!child.execute()) {
1109                                                 // 終了したら削除
1110                                                 children.splice(ci, 1);
1111                                                 --cl;
1112                                         }
1113                                         else {
1114                                                 ++ci;
1115                                         }
1116                                         // 子スレッドで例外が起きていたら一番最初のものを保存
1117                                         // Note: _errorThread が null の場合、その例外はまだ親に伝播するべきではないことを示す
1118                                         if (child._error != null && child._errorThread != null && error == null) {
1119                                                 error = child._error;
1120                                                 errorThread = child._errorThread;
1121                                                 child._error = null;
1122                                                 child._errorThread = null;
1123                                         }
1124                                 }
1125                         }
1126                        
1127                         return internalExecute(error, errorThread);
1128                 }
1129                
1130                 /**
1131                  * このスレッドを実行します.
1132                  *
1133                  * <p>子スレッドは実行されません。</p>
1134                  *
1135                  * @param       error   ここに来るまでに発生したエラー
1136                  * @param       errorThread     エラーが発生した場合、その発生元のスレッド
1137                  * @return      このスレッドの実行が継続していれば true、そうでなければ (実行が終了したら) false
1138                  * @private
1139                  */
1140                 private function internalExecute(error:Object, errorThread:Thread):Boolean
1141                 {
1142                         if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) {
1143                                 if (error != null) {
1144                                         // 待機状態で子スレッドによる例外発生していた場合は無理やり起きる
1145                                         // モニタに対して待機セットから抜けることを伝える
1146                                         _waitMonitor.leave(this);
1147                                         _waitMonitor = null;
1148                                         // state を切り替える
1149                                         _state = _runningState;
1150                                 }
1151                                 else {
1152                                         // 例外が発生していない場合はここでリターン
1153                                         return true;
1154                                 }
1155                         }
1156                        
1157                         // 今回実行する実行関数
1158                         var runHandler:Function = null;
1159                         // エラーハンドラ
1160                         var errorHandler:ErrorHandler = null;
1161                        
1162                         if (error != null) {
1163                                
1164                                 // 例外が発生していた場合は例外ハンドラを選択する
1165                                 errorHandler = getErrorHandler(error);
1166                                
1167                                 if (errorHandler != null) {
1168                                         // ハンドラが見つかった場合
1169                                         // 例外が子から伝播してきた場合、割り込まれていると考え実行関数を保存する
1170                                         if (errorThread != this) {
1171                                                 _savedRunHandler = _runHandler;
1172                                         }
1173                                         else {
1174                                                 // 子からの伝播でない場合、自力で処理したということで保存されている例外をクリア
1175                                                 _error = null;
1176                                         }
1177                                         // 実行関数をエラーハンドラに設定
1178                                         runHandler = errorHandler.handler;
1179                                 }
1180                                 else {
1181                                         // 見つからなかった場合はこのスレッドは終了フェーズに移行し親に例外を伝播する
1182                                         if (_runningState != ThreadState.TERMINATING) {
1183                                                 // 既に終了フェーズでない場合のみ
1184                                                 // state を終了フェーズに切り替える
1185                                                 _state = ThreadState.TERMINATING;
1186                                                 _runningState = ThreadState.TERMINATING;
1187                                                 // 実行関数を finalize に設定
1188                                                 runHandler = finalize;
1189                                         }
1190                                         // 親に伝播するよう例外を保存
1191                                         _error = error;
1192                                         _errorThread = errorThread;
1193                                 }
1194                         }
1195                         else {
1196                                 // 子スレッドによる例外が発生していない場合は前回指定された実行関数を設定
1197                                 runHandler = _runHandler;
1198                         }
1199                        
1200                         // 実行関数をリセット
1201                         _runHandler = null;
1202                         // タイムアウトハンドラをリセット
1203                         _timeoutHandler = null;
1204                         // イベントハンドラをリセット
1205                         resetEventHandlers();
1206                         // エラーハンドラをリセット
1207                         resetErrorHandlers();
1208                         // 割り込みハンドラをリセット
1209                         _interruptedHandler = null;
1210                        
1211                         // エラーハンドラが実行されようとしている場合、実行終了後に復帰できるように保存しておいた実行関数を設定
1212                         if (errorHandler != null) {
1213                                 _runHandler = _savedRunHandler;
1214                         }
1215                        
1216                         // Note: finalize の最後で wait が入って待機状態になった後に起きた等の場合に、
1217                         //       runHandler が null の状態でここに到達することがある
1218                         if (runHandler != null) {
1219                                
1220                                 // カレントスレッドを設定
1221                                 _currentThread = this;
1222                                
1223                                 try {
1224                                         // 実行関数を呼び出す
1225                                         if (errorHandler != null) {
1226                                                 // エラーハンドラである場合は例外と例外の発生元のスレッドを引数として渡す
1227                                                 runHandler.apply(this, [error, errorThread]);
1228                                                 // 自動終了が求められていれば next(null) を呼び出す
1229                                                 if (errorHandler.autoTermination) {
1230                                                         next(null);
1231                                                 }
1232                                         }
1233                                         else if (_event != null) {
1234                                                 var ev:Event = _event;
1235                                                 _event = null;
1236                                                 // イベントハンドラである場合はイベントを渡す
1237                                                 runHandler.apply(this, [ev]);
1238                                         }
1239                                         else {
1240                                                 // それ以外の場合は引数なしで呼び出す
1241                                                 runHandler.apply(this);
1242                                         }
1243                                 }
1244                                 catch (e:Object) {
1245                                         // 例外が発生した場合例外を保存
1246                                         _error = e;
1247                                         // エラーハンドラ以外で例外が発生し、かつ該当するエラーハンドラが存在する場合
1248                                         if (errorHandler == null && getErrorHandler(e) != null) {
1249                                                 // 自力で例外を回復できる可能性があるので強制的に runHandler を非 null にして次に繰り越す
1250                                                 // このとき、エラーハンドラ実行後に復帰するために runHandler を保存しておく
1251                                                 // run はダミーで意味はない
1252                                                 _savedRunHandler = _runHandler;
1253                                                 _runHandler = run;
1254                                         }
1255                                         else {
1256                                                 // それ以外の場合は例外を親に伝播する必要がある
1257                                                 // 例外が親に伝播するように発生元スレッドを設定
1258                                                 _errorThread = this;
1259                                                 // 実行関数の設定をクリアして強制的に終了フェーズに移行させる
1260                                                 _runHandler = null;
1261                                         }
1262                                        
1263                                 }
1264                                 finally {
1265                                         // カレントスレッドを元に戻す
1266                                         _currentThread = null;
1267                                 }
1268                         }
1269                        
1270                         // 今エラーハンドラを実行し、かつエラーが発生していない場合、保存しておいた実行関数はもう必要ないので破棄
1271                         if (errorHandler != null && _error == null) {
1272                                 _savedRunHandler = null;
1273                         }
1274                        
1275                         // イベントハンドラが設定された場合
1276                         if (_eventHandlers != null && _eventHandlers.length > 0) {
1277                                 // エラーが発生していなければ
1278                                 if (_error == null) {
1279                                         // 全てのイベントハンドラを登録
1280                                         for each (var eventHandler:EventHandler in _eventHandlers) {
1281                                                 eventHandler.register();
1282                                         }
1283                                         // 次に実行する実行関数が設定されていない場合で
1284                                         if (_runHandler == null) {
1285                                                 // まだ待機状態で無い場合、自動で待機状態に移行する
1286                                                 if (_waitMonitor == null) {
1287                                                         try {
1288                                                                 _currentThread = this;
1289                                                                 getEventMonitor().wait();
1290                                                         }
1291                                                         finally {
1292                                                                 _currentThread = null;
1293                                                         }
1294                                                 }
1295                                         }
1296                                 }
1297                         }
1298                        
1299                         if (_runHandler != null) {
1300                                 // 次に実行する実行関数が設定されている場合実行を継続
1301                         }
1302                         else {
1303                                 // 次に実行する実行関数が設定されていない場合
1304                                 if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) {
1305                                         // 待機状態に入っている場合は次に繰り越す
1306                                 }
1307                                 else if (_runningState == ThreadState.TERMINATING) {
1308                                         // 終了フェーズだった場合は実行を終了する
1309                                         // 自分の子スレッドを、孤児スレッドとしてトップレベルに移動する
1310                                         if (_children != null) {
1311                                                 addToplevelThreads(_children);
1312                                                 // 子スレッドは破棄
1313                                                 _children = null;
1314                                         }
1315                                         // state を終了状態に切り替える
1316                                         _state = ThreadState.TERMINATED;
1317                                         _runningState = ThreadState.TERMINATED;
1318                                         // join 用のモニタが存在(=join 待ちしているスレッドが存在)すれば notifyAll で起こす
1319                                         if (_joinMonitor != null) {
1320                                                 _joinMonitor.notifyAll();
1321                                                 _joinMonitor = null;
1322                                         }
1323                                         // 終了
1324                                         return false;
1325                                 }
1326                                 else {
1327                                         // 終了フェーズでない場合は終了フェーズに入る
1328                                         // state を終了フェーズに切り替える
1329                                         _state = ThreadState.TERMINATING;
1330                                         _runningState = ThreadState.TERMINATING;
1331                                         // 次の実行関数を finalize に設定
1332                                         _runHandler = finalize;
1333                                 }
1334                         }
1335                        
1336                         return true;
1337                 }
1338                
1339                 /**
1340                  * このメソッドをオーバーライドして、スレッドの処理を記述します.
1341                  *
1342                  * <p>start メソッドが呼び出され、スレッドの実行が開始されると、まずはじめにこのメソッドが実行関数として設定され、
1343                  * スレッドが実行されます。</p>
1344                  *
1345                  * <p>このメソッド内で next メソッドを呼び出すことにより、次の実行関数を設定することができます。
1346                  * 次の実行関数が設定されない場合、スレッドは終了フェーズへと移行します。</p>
1347                  *
1348                  * <p>next メソッドのほか、 wait, join, sleep, event, timeout, error, interrupted といった
1349                  * メソッドを呼び出すことで、スレッドの動作を様々に制御することができます。</p>
1350                  *
1351                  * @see #next()
1352                  * @see #join()
1353                  * @see #sleep()
1354                  * @see #event()
1355                  * @see #timeout()
1356                  * @see #error()
1357                  * @see #interrupted()
1358                  * @see #interrupt()
1359                  * @see #finalize()
1360                  */
1361                 protected function run():void
1362                 {
1363                        
1364                 }
1365                
1366                 /**
1367                  * このメソッドをオーバーライドして、スレッドの終了処理を記述します.
1368                  *
1369                  * <p>スレッドが終了フェーズに移行すると、必ずこのメソッドが実行関数に設定され、スレッドが実行されます。
1370                  * 例外が発生したりした場合でも、必ず終了フェーズに移行するので、スレッドが終了する前にはこのメソッドが実行されることが
1371                  * 確実に保証されています。</p>
1372                  *
1373                  * <p>このメソッドも実行関数と同じ扱いであるため、 next をはじめとするメソッドによってスレッドを制御することが可能です。</p>
1374                  *
1375                  * <p>スレッドはこのメソッドを利用して終了処理を行い、いかなる状況でも安全に終了することを保証するべきです。</p>
1376                  */
1377                 protected function finalize():void
1378                 {
1379                        
1380                 }
1381                
1382                 /**
1383                  * このスレッドの名前を整形して返します.
1384                  *
1385                  * <p>デフォルトでは、</p>
1386                  * <pre>'[' + className + ' ' + name + ']'</pre>
1387                  * <p>と等価な値が返されます。</p>
1388                  *
1389                  * <p>このメソッドの呼び出し結果は、 toString メソッドなどで使用されます。</p>
1390                  *
1391                  * @param       name    スレッドの名前
1392                  * @return      整形された名前
1393                  */
1394                 protected function formatName(name:String):String
1395                 {
1396                         return '[' + className + ' ' + name + ']';
1397                 }
1398                
1399                 /**
1400                  * このスレッドの文字列表現を返します.
1401                  *
1402                  * <p>デフォルトでは、 formatName メソッドを、このスレッドの名前を引数にして呼び出した結果です。</p>
1403                  *
1404                  * @return      このスレッドの文字列表現
1405                  */
1406                 public function toString():String
1407                 {
1408                         return formatName(name);
1409                 }
1410         }
1411 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。