プログラマ的京都生活

2011年11月06日

[]Play!触ってみた

1.2.3を使いました。

はまった

crud用のhtmlを編集しようとして、マニュアルにあるとおり以下のコマンドを実行したところ、、

play crud:ov --template Users/list

こんなエラーが。

Invalid command: crud:ov

アプリケーションの場所を明示することでうまく行った。

play crud:ov {PATH_OF_YOUR_PROJECT} --template Users/list


疑問

同じクラス内に、startとendというDateがあった場合、endはstartよりも未来であるべきというのをどう表現したらよいかわかっていない。

2011年03月10日

[]Javaでの文字のバイト列の表示

作る必要があったので、メモがてら残しておく。

なお、String#codePointAtで返ってくる値は常にUTF-16BEとしてのコードポイントという点に注意。

public static void main(String[] args) {
	String string = "あいうえお";

	for (int i = 0; i < string.length;) {
		int codePointAt = string.codePointAt(i);
		System.out.printf("\\u%s\n", Integer.toHexString(codePointAt));
		i += Character.charCount(codePointAt);        
	}
}

実行結果は以下。

\u3042

\u3044

\u3046

\u3048

\u304a

2011年02月14日

[]JSPでのスクリプトレット内での注意事項

Tomcat5.5.27からは以下のような書き方はできなくなったようだ。。

<input type="text" name="sample" value="<%= varA + ", " + varB %>">

こんな例外が出る。

Attribute value varA + ", " + varB is quoted with " which must be escaped when used within the value

対応方法は以下にありました。素晴らしい。

http://ameblo.jp/archive-redo-blog/entry-10299419792.html

2010年11月16日

[]タイマー実行

1.4まではjava.util.Timerを使うところでしたが、5.0からはconcurrentパッケージに導入されたScheduledExecutorServiceを使うべし!とEffective Javaにあります。

ということで、ちょっとお勉強。


ScheduledExecutorServiceの生成

基本的には以下のどちらかを使います。

  • Executors#newSingleThreadScheduledExecutor()
  • Executors#newScheduledThreadPool(int)

1つ目のは、スケジュールしても実行時に利用するスレッド数は常に1つというシンプルなもの。詳しくは後で。

2つ目のは、スケジュールして実行する際に並行して処理するもの。詳しくは後で。


実行(その前にRunnableとCallable)

Runnableインタフェースは昔からあるインタフェースで、runメソッドを実装する必要があります。

public void run() {
}

一方、5.0から増えたCallable<V>インタフェースは、callメソッドを実装する必要があります。

public V call() {
}

Callableを使うと、スレッドでの処理結果を受け取る事ができるようになります!


実行(scheduleメソッド)

ScheduledExecutorServiceで実装されているメソッドは3つあります。

  • schedule
  • scheduleWithFixedDelay
  • scheduleAtFixedRate

まずはscheduleから。これは更に2つあって、第一引数がRunnableかCallableかをとるものです。

Runnableバージョン。

ScheduledFuture<?> future = service.schedule(new Runnable() {
	public void run() {
		System.out.println("hello, world!");
	}
}, 1, TimeUnit.SECONDS);

1秒後にhello, worldを出力します。

次はCallableバージョン。

ScheduledFuture<Integer> future = service.schedule(new Callable<Integer>() {
	public Integer call() throws Exception {
		return 5;
	}
}, 1, TimeUnit.SECONDS);

int result = future.get();
System.out.println(result);

戻り値を取得する事ができます!

注意点は、これを実行するとプログラムが終了しない点です。

service.shutdown();

こう書くことで、呼び出し側はスケジュールされた処理が全て終わった時点で終了となります。


実行(scheduleWithFixedDelay)

定期実行させる時に使用するメソッドです。

ScheduledFuture<?> future = service.scheduleWithFixedDelay(new Runnable() {
	
	public void run() {
		System.out.println("あ");
	}
}, 1, 2, TimeUnit.SECONDS);

この場合、1秒後に処理が開始され、処理が終わってから2秒後にまた処理が開始され、、という風に実行します。

次の周期までに処理が終わっていなかった場合は、処理終了を待ってからすぐ実行されます。

止めるには、

service.shutdown();

とするか、次のようにするかのどちらかです。

future.cancel(true);
service.shutdown();

実行(scheduleAtFixedRate)

さきほどのscheduleWithFixedDelayとぱっと見は非常に似ています。

こちらは、再実行のタイミングが異なります。処理終了からどれだけ待つかという意味になります。

ScheduledFuture<?> future = service.scheduleAtFixedRate(new Runnable() {
	
	public void run() {
		System.out.println("あ");
	}
}, 1, 2, TimeUnit.SECONDS);

スケジュールの同時実行

シングルスレッド編。

同時に処理されるように5件をスケジュール。

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

Runnable command = new Runnable() {
	public void run() {
		try {
			Thread.sleep(1 * 1000);
			System.out.println("Thread:" + Thread.currentThread().getId());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
};

service.schedule(command, 1, TimeUnit.MICROSECONDS);
service.schedule(command, 1, TimeUnit.MICROSECONDS);
service.schedule(command, 1, TimeUnit.MICROSECONDS);
service.schedule(command, 1, TimeUnit.MICROSECONDS);
service.schedule(command, 1, TimeUnit.MICROSECONDS);

service.shutdown();

実行結果としては、ゆっくりと5sかけて、以下の結果が表示されます。

Thread:7
Thread:7
Thread:7
Thread:7
Thread:7

スレッドIDは全て同じ値を指している事が分かります。

つまり、実行は単一スレッドで行っているということですね。


次にスレッドプール編。

ScheduledExecutorServiceの生成部分だけ変えます。

ScheduledExecutorService service = Executors.newScheduledThreadPool(5);

実行結果は、1sで以下の結果が表示されます。

Thread:8
Thread:9
Thread:7
Thread:11
Thread:10

すべて別のスレッドIDが振られています。

もう予想が付きますが、宣言部を2に変えて実行します。

ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

実行結果はこんな感じ。

Thread:8
Thread:7
Thread:8
Thread:7
Thread:8

スレッドIDは2種類ですね。

2010年11月11日

[]エスケープ処理

Java上で文字列のエスケープ処理がしたい場合は、commons-langのStringEscapeUtilsを使うのがおススメ。

String escapeXml = StringEscapeUtils.escapeXml("xml");
String escapeHml = StringEscapeUtils.escapeHtml("html");
String escapeSql = StringEscapeUtils.escapeSql("sql");