感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

Javaでマルチスレッドプログラミングの基本の復習。extends Threadとimplements Runnable。

スポンサーリンク

スレッドって何?

プログラムにはアプリケーションの命令を最初から1つずつ順番に実行するための実行制御がある。
この実行制御の流れを実行スレッドと呼ぶ。

で、複数のスレッドを同時に実行させることをマルチスレッドプログラミングという。

マルチスレッドとはいうものの、CPUを1つしか搭載していないマシンでは、実際には同時に実行はしていない。
短い時間で処理を切り替えながら実行していて、これを時分割処理(タイムスライス)という。

複数の処理がこまめに切り替わって実行することにより、あたかも同時実行しているように振舞っている。
あるスレッドを一定時間実行した後、別のスレッドに実行を譲っているというわけ。

Threadクラスを使用したスレッドの作成

package examples.thread;

public class MyThread extends Thread {

	private String myName;
	public MyThread(String myName) {
		this.myName = myName;
	}

	public void run() {
		for (int i=0; i < (100*1000); i++) {
			if (i > (100*1000 - 15)) {
				System.out.println(myName + ":" + i);
			}
		}
		System.out.println(myName + " is END!");
	}

	public static void main(String[] args) {
		Thread t1 = new MyThread("one");
		Thread t2 = new MyThread("two");
		t1.start();
		t2.start();
	}
}

結果はこうなる。

one:99999
one is END!
two:99986
two:99987
(略)
two:99999
two is END!

Runnableインターフェースを使用したスレッドの作成

package examples.thread;

public class MyThread implements Runnable {

	private String myName;
	public MyThread(String myName) {
		this.myName = myName;
	}

	public void run() {
		for (int i=0; i < (100*1000); i++) {
			if (i > (100*1000 - 15)) {
				System.out.println(myName + ":" + i);
			}
		}
		System.out.println(myName + " is END!");
	}

	public static void main(String[] args) {
		MyThread my1 = new MyThread("one");
		MyThread my2 = new MyThread("two");
		Thread t1 = new Thread(my1);
		Thread t2 = new Thread(my2);
		t1.start();
		t2.start();
	}
}

結果はこうなる。

two:99999
two is END!
・・・
(略)
one:99986
one:99987
one:99998
one:99999
one is END!

このRunnableインターフェースは、中を見るとこんな感じの単純な抽象クラスである。

public interface Runnable {
    public abstract void run();
}

で、このRunnableを引数に、Threadをインスタンス化する。

Thread t1 = new Thread(runnable);

このThread()のコンストラクタは以下のようになっている。

public Thread(Runnable target) {
	init(null, target, "Thread-" + nextThreadNum(), 0);
}

このinitで、Threadクラスのプロパティ「target」に引数のRunnableがセットされる。

で、Thread#start()メソッドなんだけど、こんな感じになっている。

public synchronized void start() {
/**
 * This method is not invoked for the main method thread or "system"
 * group threads created/set up by the VM. Any new functionality added 
 * to this method in the future may have to also be added to the VM.
 *
 * A zero status value corresponds to state "NEW".
 */
    if (threadStatus != 0 || this != me) {
    	throw new IllegalThreadStateException();
    }
	group.add(this);
	start0();
    if (stopBeforeStart) {
    	stop0(throwableFromStop);
	}
}

private native void start0();

このstart()メソッド内で呼び出しているstart0()についている修飾子「native」というのは、メソッドだけに適用できるもので、
この「native」をつけて宣言されたメソッドは、そのメソッドの実装がCとかC++とか、Java以外の言語で記述されコンパイルされていることを意味する。

マルチスレッドで処理を動かしている部分はJava以外で書かれているのかね。
start()メソッドのコメントにも「このメソッドはVMによって作られたmainメソッドやsystemグループからは実行されません」みたいなことを書かれているし。

参考

SUN教科書Javaプログラマ(SJC-P)

SUN教科書Javaプログラマ(SJC-P)

基礎の基礎を勉強する時はいつもこれを見直す。
まぁ、今読むとすごく基本的すぎる感はするけど、最初はものすごくお世話になった。

マルチスレッドの勉強は続きます。