Threadとは何だ?
今までThreadというものを特に意識せずに生きてきたのですが、本の中にConcurrencyやらThreadやらと言った文字を見かけて何も知らないことに気づき勉強し始めました。
Threadの基本的な考え方
CPUというコンピューターの頭脳は命令を一つづつ実行する。その実行の流れのことをThreadという。
一般的なプログラムはシングルスレッドであり、複数の命令を逐次的に実行するが、マルチスレッドにすると、複数のスレッドを高速で切り替えながら実行できる。(補足下記)
- シングルコアの場合:高速に切り替えながら実行(疑似並列)
- マルチコアの場合:本当に同時に実行(真の並列)
シングルスレッド
3人のお客さんから同時に注文が入っても、
カレーを作ってから、パスタを作って、その後オムライスを作る
マルチスレッド
カレー、パスタ、オムライスを同時に切り替えながら作る。
(玉ねぎを炒めたら、麺を茹でて、その後ひき肉を作るなど)
JavaのThreadインスタンスの作り方
JavaのThreadインスタンスはRunnableの実装を受け取って作る。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.prinltn("カレーを作るよ");
}
});
あるいはラムダ式で
Thread t2 = new Thread(() -> {
System.out.println("パスタを作るよ!");
});
Threadに関する重要なメソッド
start()
start()で新しいスレッドが作られます。
単純な例
package org.example;
public class ThreadProblem1 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("こんにちは");
});
Thread t2 = new Thread(() -> {
System.out.println("こんばんは");
});
t1.start();
t2.start();
}
}
上の例だと、t1とt2というスレッドが非同期で実行される。そのため、「こんにちは」と「こんばんは」の順序はランダムである。間違って.run()をしてしまうとThreadの意味がまったくない同期実行になる。
package org.example;
//誤った例
public class ThreadProblem1 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("こんにちは");
});
Thread t2 = new Thread(() -> {
System.out.println("こんばんは");
});
t1.run();
t2.run();
}
}
こうしてしまうと、「こんにちは」が必ず「こんばんは」より前にprintln()される。
join()
join()を呼ぶとThreadが終わるまで待つことが出来ます。
package org.example;
public class ThreadProblem1 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println("こんにちは");
});
Thread t2 = new Thread(() -> {
System.out.println("こんばんは");
});
t1.start();
t1.join();
t2.start();
}
}
このようにすると、t1をstart()して、t1.join()でt1 のスレッドが終わるまで待つので、必ず「こんばんは」は「こんにちは」のあとに来るようになります。