続いて Command クラスです。クライアントへ送られているデータの実体は、この Command クラスインスタンスです。
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71:
package paraselene.gui.logic; import paraselene.*; import paraselene.ajax.*; import java.io.*; import java.util.*; import javax.servlet.http.*; public class Command extends Thread implements Serializable { public static final String KEY = "cmd"; private String[] cmd; private HttpSession session; private static HashMap<Command, Command> running = new HashMap<Command, Command>(); public boolean finish = false; public String echo; public Command() {} Command( HttpSession s, String[] c ) { session = s; cmd = c; synchronized( running ) { running.put( this, this ); } start(); } public void run() { Command last = new Command(); last.finish = true; try { ProcessBuilder pb = new ProcessBuilder( cmd ); Process pro = pb.redirectErrorStream( true ).start(); BufferedReader r = new BufferedReader( new InputStreamReader( pro.getInputStream(), System.getProperty( "file.encoding" ) ), 1024 ); while ( true ) { String str = r.readLine(); if ( str == null ) { try { pro.exitValue(); } catch( Exception e ) { try { Thread.sleep( 200 ); continue; } catch( Exception ee ){} } break; } Command data = new Command(); data.echo = new Text( str ).toString( HTMLPart.StringMode.BODY ); Ajax.add( session, KEY, data ); } r.close(); } catch( Exception ex ){ last.echo = new Text( ex.toString() ).toString( HTMLPart.StringMode.BODY ); } Ajax.add( session, KEY, last ); synchronized( running ) { running.remove( this ); } } }
直接関係ない説明となりますが、private static HashMap<Command, Command> running へ、スレッド開始時に this インスタンスを登録し、スレッド終了時に this を削除しています。
java のメモリ管理としてガベージコレクションがあり、どこからも参照されていないインスタンスは自動的に解放されます。
ところが、これはスレッドクラスにも当てはまり、たとえスレッドが実行中であってもインスタンスを参照している変数が皆無であれば、そのインスタンス自身が解放されてしまう事があります(スレッドは突然終了する)。
実行中の Command を参照する変数は存在しません。そのため、this 参照を維持する目的で running を使用しています。