2009年6月5日金曜日

AWT マルチスレッドの一時停止/再開

・synchronized文
 オブジェクト同期の為のもの
 ブロック内の処理を行っている間、引数に指定したインスタンスに外部からアクセスできないようにする

synchronized(インスタンス){
実行する処理
}


・スレッドの一時停止
 notify/notifyAllが呼び出されるまでスレッドを待機させる。
 引数はタイムアウト時間で、タイムアウトすると自動的にスレッドが再開する。


Object.wait();
Object.wait(long値);


・スレッドの再開
 notify:オブジェクトのモニタで待機中のスレッドを1つ再開する。
 notifyAll:オブジェクトのモニタで待機中の全てのスレッドを再開する

Object.notify();
Object.notifyAll();


例.

public class MultiApp2 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

Button b1;
Panel p1;
int num =1;

public static void main(String[] args) {
new MultiApp2();
}

public MultiApp2(){
this.setSize(300,200);
p1 = new Panel();
this.add(p1,BorderLayout.CENTER);
b1 = new Button("Click");
b1.addActionListener(this);
this.add(b1,BorderLayout.SOUTH);
this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
p1.setLayout(new GridLayout(num++,1));
Random rnd = new Random();
TimeLabel tl1 = new TimeLabel();
tl1.end = rnd.nextInt(90) + 10;
tl1.delay = rnd.nextInt(2500) + 500;
p1.add(tl1);
p1.doLayout();
}
}

class TimeLabel extends Label implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
int num = 0;
int end = 100;
int delay = 1000;
boolean kiss_of_death = false;
boolean pending = false; // 一時停止用フラグ

TimeLabel(){
this.setText("count: 0");
this.setFont(new Font("SansSerif",Font.BOLD,18));
this.setForeground(Color.blue);
this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent ev){
setPending(!pending);
}
});
new Thread(this).start();
}

public void run(){
while(!kiss_of_death){
this.setText("count: " + num++);
if(num == end){
num=0;
}
try{
Thread.sleep(delay);
synchronized(this){
if(pending){
wait(); // 一時停止
}
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}

// 一時停止/再開を行うメソッド
public synchronized void setPending(boolean f){
pending = f;
if(pending){
setForeground(Color.red);
}
else{
setForeground(Color.blue);
notify();
}
}
}

0 件のコメント:

コメントを投稿