Java で, オブジェクト自体にタイムアウト機能を持たせることを考えた. (普通ならば, 外部のオブジェクトが監視するのかな??)
2021.11.30追記: 以下記事が壊れた.
コード
<div class="outline-text-3" id="text-unnumbered-2">
<p>
こんなコードを書いた. タイムアウトになったら, 自分自身を Set から削除する.
</p>
<p>
[sourcecode language="java" title="" ] import java.util.HashSet; import java.util.Set; import java.util.Collections;
</p>
<p>
public class TimeoutObjectSample { public static void main (String[] args) { new B (); } }
</p>
<p>
class B { Set<A> set;</p>
<p>
public B () { set = Collections.synchronizedSet ( new HashSet<A>() ); A a = new A (this);</p>
<p>
set.add (a); System.out.println ("size is " + set.size ()); a.start (); }
</p>
<p>
public synchronized Set<A> getSet () { return set; }</p>
<p>
}
</p>
<p>
class A { B parent;
</p>
<p>
public A (B parent) { this.parent = parent; }
</p>
<p>
void start () { System.out.println ("start");
</p>
<p>
new Thread (new Runnable () {
</p>
<p>
public void run () { try{ Thread.sleep (1000); } catch (InterruptedException e){ } finally { Set<A> set = parent.getSet (); System.out.println ("I will die"); set.remove (this); System.out.println ("size is " + set.size ()); } } }).start (); } } [/sourcecode]</p>
<p>
しかし, これがうまく動かない. 期待値は最後に Set の要素数が 0 になること.
</p>
<p>
[sourcecode language="language" title="" ] size is 1 start I will die size is 1 [/sourcecode]
</p>
<p>
もう少し調べてみる. 以下を Thread の内部と外に仕込んだ.
</p>
<p>
[sourcecode language="java" title="" ] System.out.println (this); System.out.println (this.getClass ()); [/sourcecode]
</p>
<p>
どうも Runnable () クラスの内部と外部では, this を呼んでも別のクラスをさしているようだ.
</p>
<p>
[sourcecode language="language" title="" ] size is 1 start A@5df86e79 class A A$1@5f92b8f5 class A$1 I will die size is 1 [/sourcecode]
</p></div> </div> </div>
<div id="outline-container-unnumbered-3" class="outline-2">
<h2 id="unnumbered-3">
無名クラスに引数を渡す
</h2>
<div class="outline-text-2" id="text-unnumbered-3">
<p>
this でさす内容が違うならば, this をしなければよいのでは?? ということで, 無名クラスにパラメータを渡す方法をしらべる.
</p>
<p>
どうやら, 無名クラスのなかに, メソッドを定義すればよいようだ.
</p>
<ul class="org-ul">
<li>
<a href="https://www58.atwiki.jp/chapati4it/pages/61.html">ちゃぱてぃ商店 IT 部 @ ウィキ - Java/ サンプル/ 無名クラスにパラメータを渡す</a>
</li>
</ul>
<p>
ということで以下を変更
</p>
<ul class="org-ul">
<li>
無名クラスのなかに, パラメータをうけとる属性を作成
</li>
<li>
無名クラスのメソッドでパラメータをセットする setter を作成. このメソッドは自分自身 (Runnnable) を返す.
</li>
<li>
スレッドを起動する前に, パラメータをセットする.
</li>
</ul>
<p>
[sourcecode language="java" title="" ] import java.util.HashSet; import java.util.Set; import java.util.Collections;
</p>
<p>
public class TimeoutObjectSample { public static void main (String[] args) { new B (); } }
</p>
<p>
class B { Set<A> set;</p>
<p>
public B () { set = Collections.synchronizedSet ( new HashSet<A>() ); A a = new A (this);</p>
<p>
set.add (a); System.out.println ("size is " + set.size ()); a.start (); }
</p>
<p>
public synchronized Set<A> getSet () { return set; }</p>
<p>
}
</p>
<p>
class A { B parent;
</p>
<p>
public A (B parent) { this.parent = parent; }
</p>
<p>
void start () { System.out.println ("start"); System.out.println (this); System.out.println (this.getClass ());
</p>
<p>
new Thread (new Runnable () { A a; int time;
</p>
<p>
public Runnable setParam (A a, int time) { this.a = a; this.time = time; // 自分自身を返す. return this; }
</p>
<p>
public void run () { try{ Thread.sleep (time); } catch (InterruptedException e){ } finally { Set<A> set = parent.getSet (); System.out.println ("I will die"); set.remove (a); System.out.println ("size is " + set.size ()); } } }.setParam (this, 1000) ).start (); } } [/sourcecode]</p>
<p>
これでうまくいきました.
</p></div> </div>