「synchronizedメソッド」と「相互排他ロック」
上記以外にスレッドを制御するためのJava文法として「synchronized」というキーワードがあります。これは、複数のスレッドから同時にアクセスされることを防ぐための機構で、2通りの使い方があります。
1つは上記のようにメソッドに付けて使用します。こうしたメソッドを「synchronizedメソッド」と呼びます。
synchronized void foo() { for (int i = 0; i < 10; i++) { System.out.println(i); } }
synchronizedが付いたメソッドは、そのメソッドが複数のスレッドから呼び出されたとしても、必ず現在実行中のスレッドでメソッドが終了してから次が呼び出されます。
もう1つは、以下のように使用します。
int[] array = new int[10]; void foo() { synchronized (array) { for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } } void bar() { synchronized (array) { for (int i = 0; i < array.length; i++) { array[i] += i; } } }
synchronizedの後ろで指定されているのは「相互排他ロック」といいます。上記例ではarrayという配列で相互排他を行っており、複数スレッドからfoo()メソッドとbar()メソッドにアクセスした場合、以下のような動作になります。
Trimisでは、ユーザースレッド(自分で作成したスレッド)が1つしかなく、システムスレッドと同期をしなくてもよいように設計しているためsynchronizedは使用していませんが、これからもっともっとJavaプログラムを作っていくなら、いつかきっと必要になるときがきますので、動作の概念をよく理解して、迷ったら読み返してみてください。
メインループ
さて、追加したコードに説明を戻します。run()メソッドがスレッドの処理の本体で、今回の実装でコードがたくさん追加されています。メソッドの最初に定義されているxとyは、ブロックの座標を表しています。yの値が大きいほどブロックは落下していることを表します。
同じく最初に定義されているcountは、モードが落下中であれば1つずつ増えていく変数です。これが20で割り切れる値になったら、y座標を1つ増やしています。
if (count != 0) { if (count % 20 == 0) { y++; } }
落下中は約50ミリ秒に1回の間隔でcountが1つずつ増えていくので、ブロックが自然に落ちていくのは1秒に1行ですね。このように、スリープ(一時的に停止)をしながら処理を繰り返すスレッドを、特に「メインループ」といいます。
先ほどのJavaファイルをダウンロードして、再びソースコードを差し替えて実行してみてください。
例外が発生しますよ
自動落下を実装したソースコードをコンパイルして、実行させてみたでしょうか。実行させたら落下しているブロックが一番下まで到達するのをじっと待ってみてください。コンソール部分の最後に、iDK(DOJO)とWTK(MIDP)でそれぞれ以下のメッセージが表示されます。
「Uncaught exception java/lang/ArrayIndexOutOfBoundsException.」というメッセージは、日本語にすると「キャッチされなかった例外 java/lang/ArrayIndexOutOfBoundsException.」となります。
今回はスレッドの仕組みを理解し、例外が発生するところまでを確認しました。例外は基本的には発生してはいけない「エラーのようなもの」なのですが、「発生させないようにするにはどうしなければならないのか」「発生した場合はどのようにするべきか」「発生する可能性がある場合はどうしたらよいか」などを学びつつ、途中になっている実装を次回は進めていきましょう。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 【新人なるプログラマーへ】ソースコードを読みましょう
- Eclipseではじめるプログラミング
- いまから始めるJava
- ドコモの仕様とMIDPはどう違う?
- 第1回 NTTドコモの公式開発ツールを使おう
- 第2回 実機で動作するiアプリの作成
- 第3回 メディアリソースを利用して絵と音のあるiアプリ作成
- 第4回 HTTP通信とスクラッチパッドへのアクセス
- 第5回 CGIによるGET/POSTメソッドを使った送受信
- 第6回 互換性のあるiアプリ作成法
- 第7回 iアプリを10Kbytesに収めるテクニック
- MIDPプログラミング入門
- Google Android用携帯アプリ作成のための基礎知識
- 第1回 モバイルFeliCaでHello FeliCa
- 第2回 モバイルFeliCaでスロットゲームを作ろう