マルチスレッドとは、一つのプログラムの中である処理をしながらその「間」
に別の処理(スレッド)を割り込ませる事で、まるでそのプログラムが複数の処理を同時
(並列)に行っているような効果を得られる機能です。これは非常に便利、
というより必須の機能なのですが、
注意しないととんでもない動作をする事があります。
まず、この「ブロック崩し」
を実行してみてください。難易度はvery hard にすると良いでしょう。
どうですか? ボールが通った後に白いボールが残ったり、
バーが突然水色になったりとおかしな現象が起きますね。
実は、これは本体とは別のスレッドを作り、
その中で一定時間毎にボールを移動し表示するようにしている
(そうしないとボールの移動や表示がめちゃくちゃになる)のが原因です。
では、なぜボールやバーの色がおかしくなったのか考えてみましょう。
ボールの移動部分は以下の通りです(g_screen はゲーム画面イメージscreen
に対するGraphics オブジェクト)。
g_screen.setColor(Color.black); g_screen.fillOval(oldBallX*16,oldBallY*16,16,16); g_screen.setColor(Color.cyan); g_screen.fillOval(ballX*16,ballY*16,16,16);そして、バーの移動処理部分は以下の通りです。
g_screen.setColor(Color.black); g_screen.fillRect(oldBarX*16,272,32,12); g_screen.setColor(Color.white); g_screen.fillRect(barX*16,272,32,12);この2つとも、以前のボールやバーを黒で消した後に色を設定し直し、 新しいボールやバーを描いているので、単独で見る限りどこにも問題はありません。 しかし、このボールの処理とバーの処理が「別」のスレッドで実行されているとしたら、 どうでしょうか? 例えば、まずボールを消すためにg_screen に黒を設定したとしましょう。 ここで、スレッドの切り替えが起こりバーを描くための処理でg_screen の色が白に設定されたとします。そして、処理が終わってボールを消す部分に戻ってきた時、 g_screen にはどの色が設定されているでしょうか? 黒を設定していたのに、 別のスレッドで白に変えられましたから当然白ですね。つまり、 この状態でボールを描くと、その前の文では黒に設定したはずなのに、 実際には白く表示されてしまうのです。
synchronized(this) { /*他のスレッドとは排他的実行*/ g_screen.setColor(Color.black); g_screen.fillRect(oldBarX*16,272,32,12); g_screen.setColor(Color.white); g_screen.fillRect(barX*16,272,32,12); }
synchronized 指定なしのアプレット実行
synchronized 指定なしのプログラムソース表示