データ生成部

続いて Command クラスです。クライアントへ送られているデータの実体は、この Command クラスインスタンスです。

paraselene/gui/logic/Command.java
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 を使用しています。

送信データのルール

最終更新: 2009/10/17
特に明示されていない限り、本Wikiの内容は次のライセンスに従います:CC Attribution 3.0 Unported
文書の先頭へ
SourceForge.JP
2009 © Akira Terasaki.  
Driven by DokuWiki The Apache Software Foundation