forked from: Threadの割り込みがうまくいかないことがある
stageを連打してるとClickThreadのinterruptedが実行されないことがたまにある
一回目のクリックから3秒後にMainThreadからClickThreadにinterruptしてる
interrupt されてから実行されるまで EnterFrameThreadExecutor の場合だと
1 frame 間が空く。その間に event で設定したイベントが飛んでくると、
実行順序が意図している順番と逆になる場合がある。
その場合、意図した通りに割り込みされない。
1. Thread を event, interrupted を設定して WAITNG へ。
2. interrupt をコールして割り込む。
この時点で次の実行関数は interrupted で設定された関数になるものの、
_isInterrupted は false のままである。
3. event で設定したイベントがトリガーされる。
ここで next などで実行関数を登録した場合、次の実行関数が上書きされる。
4. 上書きされた実行関数が実行されるが、この時点で _isInterrupted は false なので、
割り込まれたのかどうか、判断する方法が無い。
@see http://www.libspark.org/ticket/104
/**
* Copyright soundkitchen ( http://wonderfl.net/user/soundkitchen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vCSr
*/
// forked from ll_koba_ll's Threadの割り込みがうまくいかないことがある
// stageを連打してるとClickThreadのinterruptedが実行されないことがたまにある
// 一回目のクリックから3秒後にMainThreadからClickThreadにinterruptしてる
// interrupt されてから実行されるまで EnterFrameThreadExecutor の場合だと
// 1 frame 間が空く。その間に event で設定したイベントが飛んでくると、
// 実行順序が意図している順番と逆になる場合がある。
// その場合、意図した通りに割り込みされない。
//
// 1. Thread を event, interrupted を設定して WAITNG へ。
// 2. interrupt をコールして割り込む。
// この時点で次の実行関数は interrupted で設定された関数になるものの、
// _isInterrupted は false のままである。
// 3. event で設定したイベントがトリガーされる。
// ここで next などで実行関数を登録した場合、次の実行関数が上書きされる。
// 4. 上書きされた実行関数が実行されるが、この時点で _isInterrupted は false なので、
// 割り込まれたのかどうか、判断する方法が無い。
//
// @see http://www.libspark.org/ticket/104
//
package
{
import flash.display.*;
import org.libspark.thread.Thread;
import org.libspark.thread.EnterFrameThreadExecutor;
public class InterruptTest extends Sprite
{
public function InterruptTest()
{
Thread.initialize(new EnterFrameThreadExecutor())
new MainThread(this).start();
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
import org.libspark.thread.Thread;
class MainThread extends Thread
{
private var _clickThread:ClickThread;
private var _target:Sprite
public function MainThread(target:Sprite)
{
_target = target;
}
protected override function run():void
{
event(_target.stage, MouseEvent.CLICK, hoge);
}
private function hoge(e:MouseEvent):void
{
sleep(3000);
next(exit);
_clickThread = new ClickThread(_target);
_clickThread.start();
}
private function exit():void
{
_clickThread.interrupt();
trace("MainThread exit");
}
}
class ClickThread extends Thread
{
private var _target:Sprite;
public function ClickThread(target:Sprite)
{
_target = target;
}
protected override function run():void
{
if (checkInterrupted())
{
// WAITING 状態での割り込みの場合だと、
// _isInterrupted が true にならないため、
// ここでも割り込まれてるのか判別出来ない :-(
trace('iregular exit...');
return;
}
event(_target.stage, MouseEvent.CLICK, click);
interrupted(exit);
}
private function click(e:MouseEvent):void
{
trace("click");
run();
}
private function exit():void
{
trace("exit!!!!!");
}
}