講座2 waitによるウェイト



 Threadクラスの静的メソッドであるsleepを使用すれば一定時間とめる事ができるが、Objectクラスの中にもwaitというメソッドがある。これを使って一定時間プログラムの実行を止める方法を紹介しよう。
 1秒間止めようと単にwait(1000)とやると実行時に以下のようなエラーが出る。
java.lang.IllegalMonitorStateException: current thread not owner 
        at test.start(test.java:15)
        at test.main(test.java:5)

 しかし、このメソッドをsynchronized修飾子の中に入れてやり、次のようなメソッドを作成するとうまくいく。
public synchronized void sleep(long msec)
{	//指定ミリ秒実行を止めるメソッド
	try
	{
		wait(msec);
	}catch(InterruptedException e){}
}
 このメソッドを自作のクラスに追加すればsleep(1000)とするだけで1秒間実行を止めることができるのだ。しかも単一スレッドなので動作は安定しており、軽い。
 しかし、何か制限が付いているのではないかと考える人もいるだろう。実はその通りである。アプレットではstart()メソッドが終了して初めてアプレットが開始されるようになっている。だからstart()メソッド内では使うことができず、それどころか新たにメソッドを呼び出してそこで使用してもstart()メソッドは終了しないので、アプレットでは使うことはできない(ループせずに数秒後にアプレットを開始させるといった使い方も考えられるが...)。
 というような理由から今回はアプリケーションのサンプルを用意した。手前がスレッドを使った場合、後が今回作成したメソッドを使用した場合である。

/** [ThreadTimer.java] スレッドを使用 */
import java.awt.*;
public class ThreadTimer extends Frame implements Runnable
{
	Thread th;
	long count=0;
	public static void main(String[] args)
	{
		new ThreadTimer();
	}
	public ThreadTimer()
	{
		resize(140,50);	//ウインドウサイズを140x50に設定
		setTitle("ThreadTimer");
		show();
		start();
	}
	private void start()
	{
		th=new Thread(this);	//スレッドを生成
		th.start();			//スレッドを開始
	}
	public void run()
	{
		while(true)
		{
			count++;
			repaint();	//paintメソッドを呼び出す
			try
			{
				th.sleep(1000);	//1秒間止める
			}catch(InterruptedException e){}
		}
	}
	public void paint(Graphics g)
	{	//countの値を表示する
		g.setColor(Color.blue);
		g.drawString("Count : "+count,30,40);
	}
	public boolean handleEvent(Event ev)
	{
		if(ev.id==Event.WINDOW_DESTROY)
		{	//閉じるボタンがクリックされた
			th.stop();	//スレッドを停止
			dispose();
			System.exit(0);
		}
		return super.handleEvent(ev);
	}
}

/** [ThreadTimer.java] waitメソッドを使用 */
import java.awt.*;
public class WaitTimer extends Frame
{
	long count=0;
	public static void main(String[] args)
	{
		new WaitTimer();	
	}
	public WaitTimer()
	{
		resize(140,50);	//ウインドウサイズを140x50に設定
		setTitle("WaitTimer");
		show();
		start();
	}
	private void start()
	{
		while(true)
		{
			count++;
			repaint();	//paintメソッドを呼び出す
			sleep(1000);	//1秒間止める
		}
	}
	public synchronized void sleep(long msec)
	{	//指定ミリ秒実行を止めるメソッド
		try
		{
			wait(msec);
		}catch(InterruptedException e){}
	}
	public void paint(Graphics g)
	{	//countの値を表示する
		g.setColor(Color.blue);
		g.drawString("Count : "+count,30,40);
	}
	public boolean handleEvent(Event ev)
	{	//閉じるボタンがクリックされた
		if(ev.id==Event.WINDOW_DESTROY)
		{
			dispose();
			System.exit(0);
		}
		return super.handleEvent(ev);
	}
}


HOME 戻る Copyright © 2000 WakuWaku.All rights reserved.