プログラミングreport#6

名前:上原和樹
番号:065709D
所属:情報工学科1年次

課題

Report#6:Java Applet プログラム{〜01/29(Mon)}
Java Applet/AWTについて学習し、Java Appletのオリジナルプログラムを作成し 解説せよ。
ボールが横に進むアプレット
ボールが弾むアプレット

ソース

// Animation.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class anima03 extends Applet {

    MyThread thread [] = {null, null, null};
    int x [] = {50, 150, 250};
    int y [] = {200, 150, 100};
    int width, height, shift;
    Color color [] = {Color.red, Color.pink, Color.magenta, Color.blue,
          Color.cyan, Color.green};
    int col [] = {0, 3, 5};
    Button resumeButton, suspendButton;
    boolean threadSuspended = false;


    public void init(){
    shift = 30;
    width = getSize().width;
    height = getSize().height - (shift + 50);
    resumeButton = new Button("Resume");
    suspendButton = new Button("Suspend");
    add(resumeButton);
    add(suspendButton);
    resumeButton.addActionListener(new ActionAdp());
    suspendButton.addActionListener(new ActionAdp());
    }

    public void start() {
    for (int i = 0; i < 3; i++) {
        if (thread[i] == null) {
	thread[i] = new MyThread(i, y[i]);
	thread[i].start();
	    }
	    }
    }


    public void stop() {
    for (int i = 0; i < 3; i++) {
        if (thread[i] != null) {
	thread[i] = null;
	    }
	    }
    }


    public void paint(Graphics g) {
    g.setColor(color[col[0]]);
    g.fillOval(x[0], y[0], 50, 50);
    g.setColor(color[col[1]]);
    g.fillOval(x[1], y[1], 50, 50);
    g.setColor(color[col[2]]);
    g.fillOval(x[2], y[2], 50, 50);
    g.setColor(Color.black);
    g.drawLine(0, height + 79, width, height + 79);
    }

    class ActionAdp implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == resumeButton) {
	threadSuspended = false;
	myResume();
	    } else if (e.getSource() == suspendButton) {
	    threadSuspended = true;
	        }
		}
    }



    void myResume() {
    for (int i = 0; i < 3; i++) {
        thread[i].myResume();
	}
    }


    class MyThread extends Thread {

    int index, maxHeight, shift;
    double time, maxTime;

    MyThread(int index, int maxHeight) {
        this.index = index;
        this.maxHeight = maxHeight;
        time = 0.0;
        shift = height - maxHeight;
        maxTime = Math.sqrt(maxHeight / 100.);
    }

    public void run() {
        Thread thisThread = Thread.currentThread();
        while (thread[index] == thisThread) {
        while (threadSuspended) {
            synchronized(this) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
            }
         }
         repaint();
         try {
             if (time >= maxTime) {
             time = -maxTime;
             }
             y[index] = (int)(100*time*time+30+shift);
             time += 0.05;
             this.sleep(50);
         }catch (InterruputedException 3) {
         }
      }
     
      public synchronized void my Resume() {
            notify();
      }
       
       }
}

3つのボールが弾むアプレット
上記のようなプログラムを考察しアプレットを作成する

オリジナルプログラム

multi.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class multi extends Applet {

  MyThread thread [] = {null, null, null};
  int x [] = {50, 150, 250};
  int y [] = {200, 150, 100};
  int width, height;
  int shift = 10;
  Color color [] = {Color.red, Color.blue, Color.cyan};
  int col [] = {0,1,2};
  Button resumeButton, suspendButton;
  boolean threadSuspended = false;


  public void init(){
    shift = 30;
    width = getSize().width;
    height = getSize().height - (shift + 50);                               
    suspendButton = new Button("Suspend");
    add(resumeButton);
    add(suspendButton);
    resumeButton.addActionListener(new ActionAdp());
    suspendButton.addActionListener(new ActionAdp());
  }


  public void start() {
    for (int i = 0; i<3; i++) {
      if(thread[i] == null){
        thread[i] = new MyThread(i, y[i]);
        thread[i].start();
      }
    }
  }

  public void stop() {
    for (int i = 0;i<3; i++){
      if(thread[i] != null) {
        thread[i] = null;                                               
      }
  }


  public void paint(Graphics g) {
    g.setColor(color[col[0]]);
    g.fillOval(x[0], y[0], 50, 50);
    g.setColor(color[col[1]]);
    g.fillOval(x[1], y[1], 50, 50);
    g.setColor(color[col[2]]);
    g.fillOval(x[2], y[2], 50, 50);
    g.setColor(Color.black);
    g.drawLine(0, height + 79, width, height + 79); 
  }

  class ActionAdp implements ActionListener {
    public void actionPerformed(ActionEvent e){
      if(e.getSource() == resumeButton){
        threadSuspended = false;
        mResume();
      }else if(e.getSource() == suspendButton){
        threadSuspended = true;                                         
      }
    }
  }

  void mResume() {
    for (int i=0;i<3;i++) {
      thread[i].mResume();
    }
  }

  class MyThread extends Thread {
    int id,maxHeight, shift;
    double time, maxTime;

    MyThread(int id, int maxHeight){
      this.id = id;
      this.maxHeight = maxHeight;
      time = 0.0;
      shift = height - maxHeight;
      maxTime = Math.sqrt(maxHeight / 100.);
    }                                                                       
  public void run(){
    Thread thisThread = Thread.currentThread();
    while(thread[id] == thisThread){
      while (threadSuspended) {
      synchronized(this){
        try {
          wait();
        }catch (InterruptedException e){
        }
      }
    }

    repaint();
 
    try{
      x[0] += 2;
      if (x[0] >= width) {
        x[0] = 0;
      }
      x[1] += 4;
      if (x[1] >= width){                                             
        x[1] = 0;
      }
      x[2] += 6;
      if (x[2] >= width) {
        x[2] = 0;
      }

      if (time >= maxTime) {
        time = -maxTime;
      }
      y[id] = (int)(100*time*time+30+shift);
      time += 0.05;
      thisThread.sleep(50);
    }catch (InterruptedException e) {}
  }
 }
 public synchronized void mResume() {
    notify();
  }
 }
}                                                                               
実行結果

考察

スレッドについて

スレッドとは小さなプロセスみたいなもので、状態としては
新規作成、使用可能、実行中、待機中、破棄の5つの状態を有する
スレッドを作成するにはjava.langパッケージのThreadクラスを使います。
スレッドを拡張するには次のようにする。

class Thread1 extends Thread{
 publid void run(){
 }
}

をつかい、中括弧内にスレッドの処理を記述する方法をとる。
また、起動するために

Thread1 t1 = new Thread1();
t1.start();

マルチスレッドについて

マルチスレッドは1度に複数のスレッドをあつかうものである。
今回のプログラミングではボール1つにつき1つのスレッドを作成し、3つ同時 に動いているように見せるのがそれである。

スレッド間通信

マルチスレッドではスレッドの動作を協調させないと行けない。
そこで、メソッド間で通信する3つのメソッドに焦点を当てる
1.wait()メソッド
wait()メソッドは、synchronizedメソッドの実行しているスレッドでロックを解 放し、ほかのスレッドからの通知を待ちます。
2.notify()メソッド
notify()メソッドはsynchronizedメソッドまたはsynchronizedブロックを実効し ているスレッドから、そのオブジェクトのロック解放を待機しているスレッドに 対して通知を行う。 3.notifyAll()メソッド
notifyAll()メソッドは、synchronizedメソッドまたはsynchronizedブロックを 実行しているスレッドから、そのオブジェクトのロック解放を待機しているすべ てのスレッドに対して通知を送る。

これら3つのメソッドはマルチスレッドを行う上では非常に大切なことである。

参考文献、URL

独習Java 第3版 ジョセフ・オニール著
15.マルチスレッド
 http://www.fk.urban.ne.jp/home/kishida/kouza/kishou/13thread.html