トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
Java
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索
___

■ チュートリアル(Tutorial)


___

■ クラス作成

ファイル名と同じ名前のクラスを用意する。 エントリのメソッドは static void main() になる。
  // Test.java
  public class Test {
    public static void main (String[] args) {
      System.out.println("Hello World !!");
    }
  }
___

■ Compile

javac.exe をつかってコンパイルする。 バイトコード Test.class が生成される。
    javac Test.java
___

■ 実行

実行する class は main() Method をもっていなくてはならない。 バイトコードは仮想マシン ( Java VM )が解釈して実行される。 Test.class を実行するには .class を除いた名前を指定する。
    java Test
___

■ 標準入力(stdin)

import java.io.*;

class test {
        public static void main(String args[]) {
                int i = 0;
                System.out.print("何か入力してください>");
                try {
                        InputStreamReader fp = new InputStreamReader(System.in);

                        while(true) {
                                i = fp.read();
                                if (i == '\n') break;
                                System.out.print((char)i);
                        }
                        fp.close();
                }
                catch (IOException err) {
                        System.out.println(err);
                }
        }
}
___

■ プロセス(Process)


___

■ ProcessBuilder

    import java.io.*;

    ProcessBuilder pb = new ProcessBuilder("notepad");
    Process p = pb.start();  
Runtime を使う
      Runtime runtime = Runtime.getRuntime();
      Process p = runtime.exec("ping localhost");
    
      // プロセスの標準出力から取得する
      InputStream stdIn = p.getInputStream();
      int c;
      while ( (c = stdIn.read()) != -1 ) {
        System.out.print((char)c);
      }
      
      stdIn.close();

      // プロセスの終了をまつ
      int ret = p.waitFor();

      System.out.println("retcode = " + ret);
___

■ リファレンス(REFERENCE)


___

■ Integer

static Integer getInteger(String nm, Integer val) static int parseInt(String s)
___

■ io.OutputStreamWriter

http://www.javaroad.jp/java_io1.htm OutputStreamWriter は、文字ストリーム -> バイトストリームへの橋渡しの役目 * Stream とは? [ 読み込み Source ] [ Program ] // 流れができている状態 を Stream というのか ? // Buffering しないですむ のが 特徴 [ 読み込み Source ] ------------> [ Program ] // JSP からも利用可能 { // Write Sample File outFile = new File("c:/test.txt"); // File Class の Instance を使って new する FileWriter out = new FileWriter( outFile ); // 文字列データ ( \n は別途必要 ) out.write( "test" + "\n" ); out.write( 10 ); // 書き込みストリームをとじる out.close(); }
___

■ io.File

* http://www.javaroad.jp/java_io8.htm * FS 関連の Service を提供する Fileクラスには ファイル・ディレクトリの作成、PATH名の調査 read権・write権の調査などファイル・ディレクトリに対して動作する様々なメソッドが用意 Fileクラスのオブジェクトは FileReaderクラス, FileWriterクラスなどの ファイル入出力関連のオブジェクトを生成する際の引数としても使用される
___

■ sql.ResultSet

// ResultSet オブジェクトの現在行にある指定された列の値を // Java プログラミング言語の int としてとる int getInt(String columnName) // 2 OKU をこえる値は long でないと ERROR int getLong(String columnName)
___

■ URLEncode

java.net.URLEncoder クラスを使用するために java.net.*パッケージのインポートを宣言
  // urlencode の check にも利用できる
  // Default が SJIS 
  String enc = URLEncoder.encode( "あああ" );


  // encode() メソッドはスタティックなのでインスタンスを生成せずに使える
  String value = URLEncoder.encode( now.toString() );

___

■ sql.ResultSetMetaData

REF http://www008.upp.so-net.ne.jp/kikuta/jdbcnote/jdbc5_7.html DESC DB の MetaData をとれる このときは getInt() とか といったメンドイことはしなくても OK
     ResultSetMetaData rsmeta = rs.getMetaData();
    
    // column 数
    int nrCol  = rsmeta.getColumnCount();

    // column 型名
    String rsmeta.getColumnName( i );

    // column 型 ( Enum )
    int rsmeta.getColumnType( i );

    // column 型名
    String rsmeta.getColumnTypeName( i );

    
    out.println( "< table border=1>" );

    // Header
    out.println( "< tr>" );
    for( int i=1; i< =nrCol; i++ ){
      String label = rsmeta.getColumnName(i);
      out.println( "< th>" + label + "< /th>" );
    }
    out.println( "< /tr>" );
    
    while(rs.next()){
      out.println( "< tr>" );
      for( int i=1; i< =nrCol; i++ ){
        int type = rsmeta.getColumnType(i);

        if ( type == Types.CHAR ) {
          out.println( "< td>" + rs.getString( i ) + "< /td>" );
        }
        else if ( type == Types.INTEGER ) { 
          out.println( "< td>" + rs.getInt( i ) + "< /td>" );
        }
        // MySQL で指定した 型と同じ
        else if ( type == Types.BIGINT ) { 
          out.println( "< td>" + rs.getInt( i ) + "< /td>" );
        }
      }
      out.println( "< /tr>" );
    }
    out.println( "< /table>" );
___

■ tmp


    // 接続元の Client をえる
    String host = request.getRemoteHost();

___

■ System.out


    // RET "null" という文字列が表記される
    // ( DB のデータをはくときに注意 )
    String s = null;
    System.out.println( s );

___

■ util.Date

REF Date http://www.javaroad.jp/java_date1.htm
___

■ util.Calendar

DESC 現在の日付をえる
   class Foo
   {
     public static void main(String[] args) {

       Calendar cal1 = Calendar.getInstance();  //オブジェクトの生成

       int year = cal1.get(Calendar.YEAR);        // 年
       int month = cal1.get(Calendar.MONTH) + 1;  // 月
       int day = cal1.get(Calendar.DATE);         // 日
       int hour = cal1.get(Calendar.HOUR_OF_DAY); // 時
       int minute = cal1.get(Calendar.MINUTE);    // 分
       int second = cal1.get(Calendar.SECOND);    // 秒

       StringBuffer dow = new StringBuffer();

       switch (cal1.get(Calendar.DAY_OF_WEEK)) {  // 曜日
         case Calendar.SUNDAY: dow.append("日曜日"); break;
         case Calendar.MONDAY: dow.append("月曜日"); break;
         case Calendar.TUESDAY: dow.append("火曜日"); break;
         case Calendar.WEDNESDAY: dow.append("水曜日"); break;
         case Calendar.THURSDAY: dow.append("木曜日"); break;
         case Calendar.FRIDAY: dow.append("金曜日"); break;
         case Calendar.SATURDAY: dow.append("土曜日"); break;
       }

       // 年、月、日、曜日、時、分、秒を表示
       System.out.println(year + "/" + month + "/" + day + " " + dow
                  + " " + hour + ":" + minute + ":" + second);
     }
   }
___

■ sql.Statement

REF http://www.fireproject.jp/feature/postgresql/programing_jdbc/execute.html#2

  // 指定された SQL 文を実行する
  int  executeUpdate(String sql) 
  
  // SELECT 文のときに使う
   ResultSet  executeQuery(String sql) 

___

■ 文字列


___

■ lang.String


  // 比較
  //      == はだめらしい strcmp と同じ
  int  compareTo(String anotherString)

  // 文字列の長さ ( 文字数 )
  // 
  int  length()

  // int -> String へ ( FactoryMethod )
  String s = String.valueOf( p );

  // i 番目 をとりだす
  char c = s.charAt(i);

  // Split
  // 指定した regexp で分割する
  String[] split(String regex) 

  // 置換
  //   2 つめは String
  String  replaceAll( String regexp, String dst )
  {

    String path = "c:\\foo\\bar\\foo.txt";
    // BAD
    //path.replaceAll( "\\", "/" );

    //OK
    //  \\\\ で \\ という文字列が RegExp Engine にわたる
    //  [\\] は [\] を意味する
    //
    path.replaceAll( "\\\\", "/" );
  }


  // 検索
  //  みつからなければ -1  
  int i = s.indexOf( "abc" );


    // 部分文字列
    // index 1 から 最後まで 
    s.subString( 1 );
    s.subString( 1, 10 );

  // Ctor はない
  {
    int i = 10;

    // BAD
    //String path = i;

    //OK
    String path = "";
    path = i;
  }    

  
  // 指定した Encode で String をバイトシーケンスに符号化して配列にセット
  byte[]  getBytes( String code ) 

  {
    String s = "ABC";
    byte[] a = null;

    try {
      // SJIS Code でバイト列をかえす
      a = s.getBytes("SJIS");
    }
    catch ( Throwable e ) {
      System.out.println( "error" );
    }  
    // RET: 65 66 67
    for( int i=0; i< a.length; i++ ){
      System.out.println( a[i] );
    } 
  }

  BAD
    String[] list = ( ret[0][6] ).split(".");

  OK
    String[] list = ( ret[0][6] ).split("\\.");
___

■ StringBuffer

POINT 文字列バッファは String と似ているが、変更できる点が異なる。 WARNING String 型とは互換性はないため、変換が必要
    String str = s.toString();
    // 長さ
    s.length()

    // 先頭の文字を消す
    s.deleteCharAt( 0 );

    // 参照
    s.charAt( 0 );
    
    // 追加
    s.append( "test" );
    
    // 文字以外でも文字列表現で追加できる
    s.append( 0 );    
    s.append( obj );    

    // 部分文字列
    s.subString( 0, 3 );

    // すべて削除
    s.delete( 0, s.length() );

  WARNING
    代入できない
    s = "";

___

■ SYNTAX


___

■ 制御構文

___

■ for

    for( int i=0; i< a.length; i++ ){
      s += a[i] + "_";
    } 

    System.out.print( s + "," );

___

■ 型

大きくわけて 2 種類 基本型: boolean、 char、byte、short、int、long、float、double 参照型: クラス型、インタフェース型、配列型 基本型の型変換 データ格納領域がより広い型への変換を要求した時に、暗黙的な型変換をする だから int -> boolean は当然ない boolean なし char int, long, float, double byte short, int, long, float, double short int, long, float, double int long, float, double long float, double float double double なし 基本型のキャスト( C 同様 ) キャストとはプログラマが[ 意識的 ]に行う変換処理 型変換では変数の変換処理をできない時にキャストを使用する キャストは変換したい型を( )で囲み、変換元の変数の前に指定することでする
___

■ Cast(型変換)

キャストのルール boolean 型以外の基本型の変数を、他のbooleanが対外の基本型の変数にキャストできる キャストはデータ格納領域が広くなるキャストでも、データ格納領域が狭くなるキャストでも OK データ格納領域が広くなるキャストの場合は、キャストを指定しなくても、 必要な場合には、暗黙的な型変換がされる. boolean 型はどの型へもキャストできない
___

■ import

REF importの機能 DESC import 宣言をすることで class の指定を 省略できる
    // sql 以下を[*] 全指定( wildcard )
    import java.sql.*;
    
    // single-type-import
    //  
    import java.util.Date;

    // type-import-on-demand
    //  
    import java.util.*

    // java.util だけでなく 
    import java.util.*;

    // java.util.jar パッケージのクラスも利用する
    import java.util.jar.*;;
WARNING 直下 のみ を検索する
___

■ Scope


  // Block Scope
  {
    int i = 128;
  }

  // ERROR : シンボルを見つけられません。
  System.out.println( i );



    int i = 10;
    System.out.println( i );
    // block Scope があるくせに, 同一の Symbol ってだめらしい
    {
      // ここで怒られる
      // ERROR : i は main() で定義されています
      int i = 10;

      System.out.println( "inner = " + i );
    }
    System.out.println( i );
___

■ Array(配列)

SYNTAX 型[ ] 配列名;

  // int 型の配列 intArray を宣言  
  int[] intArray;   
  
  // 
  char[] charArray = new char[10];


  // 要素数
  int nr = a.length;

// 初期化子は配列生成時に直接データを代入して配列を生成する方法です 初期化子を指定した場合の配列サイズは代入するデータの数で決まる String[] stringArray = {"Sunday", "Monday", "Tuesday"}; //String型の配列stringArrayを宣言・生成
___

■ 予約語(Reserve)

null // NULL でないよ
___

■ コンテナ(Collection)



___

■ ArrayList

POINT ArrayList は sort の機能がない add() は overload があり 任意の位置にも追加できる ArrayList() は逐次探索をする
    import java.util.*;

    ArrayList<  String > a = new ArrayList<  String >();
    a.add( "aaa" );

    // 初期バッファサイズを指定する。
    //    要素数ではないので注意。
    ArrayList( 10 ) 

    // 指定した位置の要素を削除する。
    a.remove( 0 );

    // 要素数
    a.size()

  WARNING
    [] は利用できない。get(), set() で参照をとる。
    a.get( 0 );
    a.set( i, 10 );
      
  
___

■ Map

http://www.javaroad.jp/java_collection4.htm

    import java.util.*;

    public class ExCollection7 {
      public static void main(String[] args) {
        ExCollection7 exClass = new ExCollection7();
        exClass.showFeature(new HashMap(), "HashMap");  
        exClass.showFeature(new TreeMap(), "TreeMap");  
        exClass.showFeature(new LinkedHashMap(), "LinkedHashMap");  
      }

      void showFeature(Map exMap, String s) {
        String[] tel = {"092", "06", "052", "03", "011"};
        String[] area = {"Fukuoka", "Osaka", "Nagoya", "Tokyo", "Hokkaido"}; 
        for (int i = 0; i <  5; i++) {

         // Mapに 要素 をいれる
          exMap.put(tel[i], area[i]);
        }

        // Map の 要素をみる
        System.out.println(s + " = " + exMap);
      }
    }

___

■ 例外(Exception)


  POINT
    RuntimeException 以外は 処理するコードがいる。
    コードがない場合はコンパイルエラーになる。

    RuntimeException は いつでも発生するため
    コンパイラーがチェックする意味がない。

    
     



___

■ try.catch.finally

  try {
    // 例外をスローする可能性のある処理
  } 
  catch (例外クラス型 引数名) {
    // 例外処理(例外ハンドラ)
  } 
  finally {  // 任意
    // 最後に必ず実行される( したい )処理 

      // EX file close 
  }
catch は複数指定できる。 この場合は、例外の派生先の順にすることで具体的なエラー内容を知ることができる。

    try {

    }
    catch {

    }
    // なんでも うけとると どの例外処理をしたらいいかわからない
    catch ( Exception e ) {

    }



___

■ package


  目的は
    同じ機能をもつものを Group 化して整理する
    名前の衝突をふせぐ
    Security ( 同一 package 内からのアクセス )

    // package 内にあるクラスを利用するには package名をつける

    sample.Test

___

■ packageにクラスをいれる

Package の適用範囲は File 全体.
    Package を指定しないと
      DefaultPackage に含まれる

   DefaultPackage とは
      名前をもたない Package 

  POINT
    Java API の class は どれかの Package にはいる

     // パッケージPackageAの作成
     package PackageA;  

     public class Test {  //
       public void func() {
         System.out.println("PackageAに属します");
       }
     }
___

■ packageのクラスを使う

ArrayList は java.util にある ArrayList の FullName は
    java.util.ArrayList
POINT Java の import は FullName の Type を省くため include とは異なる import 宣言がなくても class は利用できる
    // Class を使うには import する
    import java.util.ArrayList;

    // または FullName で指定する
    java.util.ArrayList<  Dog > a = new java.util.ArrayList<  Dog >();

    // java.lang は例外で FullName で指定する必要がない
     // PackageA.ExPackage インポート
     import PackageA.ExPackage;  

     public class ExPackage1 {
       public static void main(String[] args) {
         ExPackage ex = new ExPackage();  //
         ex.showName();  //
       }
     }
// Compile の指定 javac PackageB/ExPackage2B.java // dir( package )つきで call しないとだめらしい java PackageB/ExPackage2B WARNING どうやら Directory と Mapping する必要がある POINT java. ではじまるのは Sun 公認の package javax. は 標準拡張 package という はじめは 拡張 package だが, 標準ライブラリと同じくらい 一般的になった
___

■ スレッド(Thread)




    スレッドとは制御の流れのこと。
    マルチスレッドでは複数の制御の流れを作成できる。

  POINT
    スレッドは "ながら仕事" をする時に使う。


  POINT
    スレッドは次のケースで使う。

     ネットワークIOで入出力待ちをするとき
     ユーザーへの応答

___

■ スレッドをつくる

スレッドをつくる方法は2つある。
     Runnable インターフェイスを実装する
     Thread クラスを継承する。
    // 仕事をつくる
    Runnable job = new MyJob();

    // Thread には Job が必要
    Thread t = new Thread( job );

    // 実行可能 状態になる
    t.start();
POINT Thread には名前をつけることができる。 デバッグをする時に便利。
    Thread t = new Thread();

    // 名前をつけなくてもデフォルトの名前がつく
    t.setName("xxx");

    // 実行中のスレッドの名前をとる
    Thread.currentThread().getName();

Runnable を実装したクラスをスレッドで実行する。
    // スレッドで実行可能なクラス
    class Job implements Runnable
    {
      public void run() {
        while(true) {
          System.out.println("thread working" );
        }
      }  
    }; 

    public class TestRunable {
      public static void main (String[] args) {
        Job job = new Job();
        Thread t1 = new Thread( job, "test" );
        t1.start();

        System.out.println("main thread run");
      }
    } 
WARNING スレッドの run() は一度しか実行できない。 スレッドへの仕事を繰り返す場合は 無限ループさせる。
      t = new Thread();
      t.start();

      // ERROR
      //    一度したスレッドは再度実行できない。
      t.start();
      public void run() {
        while ( true ) {
          System.out.println("thread working" );
        }
      }
___

■ スレッドクラスを継承する

    public class Test extends Thread {

      public main() {

      }

    }
___

■ スレッドを止める

POINT スレッドの動作をとめるには次の方法がある。 スレッドの終了をまつ。 WARNING 一度終了したスレッドの再利用( start() )はできない。 明示的に破棄する場合は null を設定して参照を消すこと。
    class Test extends Thread {

      public static void main ( String args[] ) {
        Test t = new Test();
        
        t.start();
        
        // スレッドが生きているか質問する。
        while ( t.isAlive() ) {
        
        }
      }

      public void run() {
        System.out.println( "thread working ..." );
      }
    }
___

■ スレッドの終了をまつ

main スレッドで isAlive() で質問をしながら待つと CPU 時間を無駄に消費することになる。 そのため join() メソッドで指定したスレッドが停止するまでまつ
    // スレッドを実行して
    t.start();


    // スレッドの終了をまつ
    t.join();

    // 2 秒まつ
    t.join( 2000 );
    
___

■ 別のスレッドからとめる

スレッドは run() メソッドが完了すれば, 終了するので run() メソッドが完了するようにすればいい。 つまり終了条件となる変数の値を変更してしまえばいい。

class TestStop extends Thread {

  // 終了条件
  static volatile boolean flag = false;
 
  public static void main ( String args[] ) {
    TestStop t = new TestStop();
      
    int i = 0;
    t.start();

    System.out.println("スレッドを止めるには s と入力してください");

    try {
      InputStreamReader fp = new InputStreamReader(System.in);

      while(true) {
        i = fp.read();
        if (i == '\n') break;
        System.out.print((char)i);
      }
      fp.close();
    }
    catch (IOException err) {
      System.out.println(err);
    }

    flag = true;
  }

  public void run() {
    while ( !flag ) {
      try {
        Thread.sleep( 1000 );
      }
      catch ( Exception e ) {}
      System.out.println( "thread working ..." );
    }
  }
}


___

■ プログラムの終了とスレッドの終了

POINT プログラムが終了するのは, main() スレッドが終了する時ではなく すべてのユーザースレッドが終了した時に終わる。 スレッドには2種類あり ユーザースレッドは通常のスレッドの作成でつくられるスレッド。 デーモンスレッドはプログラムが終了するときにスレッドの終了をまつ必要がない。 デーモンスレッドの例として Java の GC がある。 デーモンスレッドにするには, start() の前に setDaemon( true )で設定をする。

    public class TestDaemon extends Thread {

      public void run() {
        while ( true ) {
          System.out.println( "daemon thread working" );
        }
      }
      public static void main (String[] args) {

        Thread t = new TestDaemon();
        t.setDaemon( true );
        t.start();

        try {
          Thread.sleep(1000 * 1);
        }
        catch ( Exception e ) {}
      }
    } 


___

■ スレッドの同期(排他)

スレッドは非同期で実行されるが、共有のデータを操作、参照する場合は 矛盾が起きないように処理を同期する必要がある。 つまり相手の動作と合わせる必要があるタイミングがある。 スレッドの同期化とは 1つのリソースに対して2つが同時に操作をしないようにすること。 複数のスレッドで同期をするには モニタを取得する。 スレッド同士を同期する方法は次の2つがある。
      synchronized メソッド
      synchronized ブロック
synchronized メソッドはメソッドの対象である( this )オブジェクトをロックする。 ロックされた場合、他のスレッドが this に相当するオブジェクトのメソッドを実行しようとすると 処理が待機する。 ロックをしてメソッドの処理が終わったスレッドはロックを解除してメソッドを抜ける。 待機していた別のスレッドはロックをかけて、そのメソッドを開始できる。 オブジェクトが自分のスレッドでロックしているかどうかを調べることもできる ただし別のスレッドがロックしているかどうかは判断できない。
      b = Thread.holdsLock( o );
      System.out.println("ロック状態 " + b );
ロックは変数ではなく、その参照先のオブジェクトに対してされる。
    synchronized ( o ) {
      
    }

    // これも同じ。 holdsLock() でチェックできる。
    Object a = o;
    synchronized ( o ) {
       system.out.println( Thread.holdsLock( a ) );
    }
class Toilet
{
  synchronized public void enter() {

    String s = Thread.currentThread().getName();

    System.out.print( s );      
    for( int j=0; j< 50; j++ ){
      System.out.print( "=");      
    } 
    System.out.print( ">\n");      
  }
}

class Human extends Thread
{
  Toilet t;
  Human( Toilet t ) {
    this.t = t;
  }

  public void run() {
    while (true) {
      t.enter();
    }
  }  
}

public class TestSync extends Thread
{
  public static void main (String[] args) {

    Toilet t = new Toilet();
    Human h = new Human(t);
    h.setName( "foo" );
    h.start();
    Human h1 = new Human(t);
    h1.setName( "bar" );
    h1.start();
  }
} 

___

■ ロックをすることは書き込み禁止とは異なる

POINT ロック/アンロックはモニタの取得、解放を意味するだけ。 オブジェクトの変数の設定はできてしまう。
___

■ タイマーを使って画像を定期的にきりかえる

___

■ デッドロック

POINT 複数のスレッドがお互いがロックしている オブジェクトをロックしようとするとデッドロックが発生する。 デッドロックを回避するには、ロックする順番を決めておくとよい。 デッドロックを起こす要因として, suspend() がある。 オブジェクトをロックした状態で suspend() をするとデッドロックの可能性があるため 利用しないほうがよい。 stop() はロック中のオブジェクトを解放するが、 処理が任意のタイミングで中断されるため、作成途中のオブジェクトができるため 利用しない方がいい。


___

■ スレッドを連携させる

スレッド間で連携した処理をするには 待機 と 通知 を使う。 あるスレッドで変更があった場合に、別のスレッド側へ通知をしてもらう。 その間は待機することで、無駄な時間( CPU 割あて )をなくすことができる。 オブジェクトの変更があるまで, 待機して変更があったら通知してもらうことで 無駄な待ち時間や処理が不要になる。 notify()/notifyAll() を利用する。 wait() メソッドでオブジェクトの状態が変更されるまで一時停止して待ち POINT wait() する側は状態の変更を待つ側 オブジェクトの状態が変わるまで待ちたい場合は, wait() を使う。 notifyAll() を使うと、 obj に対して待機しているすべてのスレッドに通知される。
public class TestWait extends Thread
{
  boolean flag = false;

  static Object o = new Object();

  public static void main (String[] args) {
    TestWait t = new TestWait();
    t.start();

    try {
      Thread.sleep( 5000 );
    }
    catch ( Exception e ) {}

    System.out.println("変更があったので、通知します。");
    try {
      Thread.sleep( 1000 );
    }
    catch ( Exception e ) {}

    // notify() するスレッドは、wait() と同じく obj をロックする必要がある。
    synchronized( o ) {
      o.notify();
    }
  }

  public void run() {
    try {
      Thread.sleep( 3000 );
    }
    catch ( Exception e ) {}

    // wait() を実行するスレッドは obj をロックする必要がある。
    // ロックをしないと、 java.lang.IllegalMonitorStateException が発生して wait() に失敗する。
    synchronized( o ) {
      try {
        System.out.println("待機しています。");
        o.wait();
      }
      catch ( Exception e ) {
        System.out.println("throw");
      }
    }

    System.out.println( "thread working ..." );
  }  
} 
wait() はタイムアウトの指定もできる。 notify() がなくても指定時間が過ぎたらスレッドを再開する。
        o.wait( 3000 );
___

■ キーボード入力したコマンドラインをスレッド側で実行する

public class TestWait2 extends Thread
{
  static StringBuffer o = new StringBuffer();

  public static void main (String[] args) {
    TestWait2 t = new TestWait2();
    t.start();
    int i = 0;

    InputStreamReader fp = new InputStreamReader(System.in);

    try {
      Thread.sleep( 500 );
    }
    catch ( Exception e ) {}

    while (true) {
      try {
        Thread.sleep( 1000 );
      }
      catch ( Exception e ) {}
 
      System.out.println("文字を入力してください。");
      StringBuffer st = new StringBuffer();

      try {
        while(true) {
          i = fp.read();
          if (i == '\n') break;
          System.out.print((char)i);
          st.append( (char)i );
        }
        //fp.close();
      }
      catch (IOException err) {
        System.out.println(err);
      }
      
      o.delete( 0, o.length() );
      o.append( st );

      // notify() するスレッドは、wait() と同じく obj をロックする必要がある。
      System.out.println("変更があったので通知します。");
      synchronized( o ) {
        o.notify();
      }
    }
  }

  // うけとった文字列を cmdline として実行する
  void cmdlineJob( String s ) {
    try {
      String t = Thread.currentThread().getName();
      System.out.println( t + "cmdlineJob = " + s );

      Runtime runtime = Runtime.getRuntime();
      Process p = runtime.exec( s );

      InputStream stdIn = p.getInputStream();
      int c;
      while ( (c = stdIn.read()) != -1 ) {
        System.out.print((char)c);
      }
      stdIn.close();

      int ret = p.waitFor();
      System.out.println("retcode = " + ret);
    }
    catch ( Exception e ) {
      System.out.println("fail");
    }
  }

  // スレッド側では キーボード文字の入力があった場合に処理を実行をする。
  public void run() {
    while ( true ) {
      String s = Thread.currentThread().getName();

      // wait() を実行するスレッドは obj をロックする必要がある。
      // ロックをしないと、 java.lang.IllegalMonitorStateException が発生して wait() に失敗する。
      synchronized( o ) {
        try {
          System.out.println( s + "待機しています。");
          o.wait();
        }
        catch ( Exception e ) {
          System.out.println("throw");
        }
        
        cmdlineJob( o.toString() );
      }
    }
  }  
} 
___

■ スレッドの優先度をつける

スレッドの優先度をつけるには Thread.setPriority() を使う。 スケジューラは実行可能状態のスレッドのうち、優先度の高いものを実行する。 優先度は 1 - 10 で指定して、値が大きいほど優先度は高い。 POINT マルチコアの環境では、実際に複数同時に実行できるため コア数より少ないスレッドの場合は数が同じくらいになる可能性がある。 カウントを表示して優先度の効果を確かめてみる。

    // スレッドへのお仕事
    class Job implements Runnable
    {
      volatile public int cnt = 0;

      // スレッドに実行させるメソッド
      public void run() {
        System.out.println("do job" );

        while ( true ) {
          cnt ++;
        }
      }
    } 

    public class TestPriority {
      public static void main (String[] args) {

        ArrayList<  Job > a = new ArrayList<  Job >();
        int nr = 10;

        int i = 0;
        for( i=0; i< nr; i++ ){
          Job job = new Job();
          Thread t = new Thread( job, "t1" );
          t.setPriority( (i%10) + 1 );
          t.start();

          a.add( job );
        } 

        while ( true ) { 

          try {
            Thread.sleep(3000 * 1);
          }
          catch ( Exception e ) {}

          for( i=0; i< nr; i++ ){
            System.out.println( " job " + (i+1)%10 + " " + a.get(i).cnt );
          } 

        }
      }
    } 



___

■ スレッドの処理を割り込む

待機中( wait(), sleep(), join() )のスレッドの処理に強制的に再開するには interrupt() を使う。 これによって メインスレッドが終了する時点で, 待機中のスレッドを停止させることができる。
___

■ GUI


  POINT
    Java では GUI の構成要素を Component という
    javax.swing.JComponent を継承する

___

■ Window

ウィンドウをつくるには JFrame を作成して表示する。 JFrame も GUI コンポーネントのひとつ。
    import javax.swing.*;
    import java.awt.*;


  public static void main() {
    // フレーム( ウィンドウ )を作成。
    JFrame f = new JFrame();
    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
    // 大きさの設定
    f.setSize( 300, 300 );

    // 位置の設定
    f.setLocation( 100, 100 );

    // 表示する。
    f.setVisible( true );
  }
メインスレッドを止めても, GUI の操作は受け付けるらしい。
    // 表示する。
    f.setVisible( true );

    // 無限ループ
    while ( true ) {
      System.out.print(".");
    }
___

■ ボタン(Button)

すべての GUI コンポーネントはフレームに追加することで、配置される。
    JFrame f = new JFrame();

    JButton b = new JButton( "click me" );
    f.getContentPane().add( BorderLayout.EAST, b );  
ボタンのコールバックを受け取るにはリスナーを追加する。 リスナーに登録するには ActionListener を実装する。
    
    class MyListener implements ActionListener {

      public void actionPerformed( ActionEvent e ) {
        System.out.println( "button clicked" );
      }
    }



ボタンオブジェクトに対してリスナー( コールバック )を登録する。
    b.addActionListener( new MyListener() );
___

■ グラフィック(Graphic.Swing)

グラフィックを描画するには JFrame.paint(Graphics g) メソッドをオーバーライドする。 Graphics は描画のためのメソッドと共にグラフィックスのステートをもつ。

    class MyFrame extends JFrame {

      public void paint(Graphics g){
        super.paint( g );

        // カラーステートを青に変更
        g.setColor(Color.BLUE);
        g.drawRect(10,60,280,180);

        // 位置 と 大きさ を指定
        fillRect( int x, int y, int width, int height );

        g.fillOval(100,100,100,100);

        // テキストを描く
        g.drawString("Swing Test", 10, 50);
      }

      MyFrame() {
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        setSize( 300, 300 );
        setVisible( true );    
      }

      public static void main() {

        JFrame f = new MyFrame();

      }
    }
ボタンを押したら色を変更するためにボタンのリスナーになる。
    class MyFrame extends JFrame implements ActionListener {

      int flag = 0;

      public void actionPerformed( ActionEvent e ) {
        flag ++;

        // 画面を更新するには再描画を要求する。
        repaint();
      }

    }
ボタンの種類を判別するには, ActionEvent.getActionCommand() を利用する。 ラベルの文字列が返ってくるので判別できる。
      if ( e.getActionCommand() == "click me" ) {
        System.out.println( "button clicked  go" );
      }
      else {
        System.out.println( "NOT button clicked  stop" );
      }
___

■ 画像を表示する


  public void paint(Graphics g){
    super.paint( g );
    Image i = new ImageIcon( "d:/test.jpg" ).getImage();
    g.drawImage( i, 0, 0, this );
  }

___

■ ネットワーク(Network)


___

■ Socket

シンプル HTTP クライアント
    import java.io.*;
    import java.net.*;
    
    public class HttpClient {
  
      PrintWriter writer;
      Socket soc;

      public void doIt() {
         try {
           soc = new Socket( "127.0.0.1", 8080 );
           writer = new PrintWriter( soc.getOutputStream() );

           //InputStreamReader s = new InputStreamReader( soc.getInputStream() );

           System.out.println( "Network につながりました " );

         }
         catch ( IOException e ) {
           e.printStackTrace();
         }

         // HTTP メッセージを投げる
         writer.println( "GET / HTTP/1.0\r\n\r\n" );
         
         try {
            InputStreamReader s = new InputStreamReader( soc.getInputStream() );
            int i = 0;
            while(true) {
              i = s.read();
              if (i == -1) break;
              System.out.print((char)i);
            }
         }
         catch ( Exception ex ){}
      }

      static void main() {
        new HttpClient.doIt();
      }

















NINJAIDX 4