13-4. シングルスレッドとマルチスレッド
シングルスレッドとマルチスレッド
2つのタスクは、2つのスレッドではなく1つのスレッドとして処理されます.
単一スレッドを使用すると、1つのタスクが完了した後に次のタスクを開始できますが、2つのスレッドを使用すると、タスクを同時に処理するように2つのタスクが交互に実行されます.
しかし、2つのスレッドがある場合、逆に、スレッド間の変換(Context Switching)が単一スレッドよりも長い時間を要することになる.
Context Switching
進行中のタスク(プロセスまたはスレッド)のステータスを保存し、次のタスクのステータスを取得します.
したがって、マルチスレッドは必ずしも良いわけではありません.場合によっては、単一スレッドでプログラミングしたほうがいいかもしれません.
単一スレッドを使用した2つのタスク
2つのタスクを完了するには32ミリ秒かかります
2つのマルチスレッド(2つ)を使用して2つのタスクを実行
8コアCPU環境でテストが行われているため、各コアはスレッドを1つ実行し、同時に2つのタスクを実行します.
「出力スクリーン」(console)という名前のリソースを共有するため、各スレッドがリソースを争っており、
結論:同じリソースを使用する2つのタスクを処理する場合、単一スレッドの速度はより速くなります.
📌 [注意]
パラレル(concurrent):単一カーネルで、タスクを複数のスレッドに分割し、順番に実行します.(物理的に同時に行われる操作ではありませんが、交代速度が速いので同時に行われているように見えます)
パラレル(Parallel):マルチコア環境では、タスクを複数のカーネルに分散し、各カーネルのスレッドを同時に処理します(実際には複数のタスクを同時に実行します).
📌 [注意]
実行中のサンプル・プロセスは、オペレーティング・システムのプロセス・スケジューラの影響を受けるため、サンプルの実行結果で測定される時間は毎回異なります.
プロセススケジューラは、プロセスの実行順序と実行時間を決定します.これは、毎回の状況に応じて異なり、スレッドに割り当てられる時間も固定されません.
異なるリソースを使用する2つのタスクを処理すると、マルチスレッドの速度が速くなります.
ex)ユーザからのデータ入力の受信、ファイルのネットワークへの転送、プリンタなどの外部機器とのI/O…
ユーザから入力値を受信して出力し、10から1秒ごとに数値を数えます.
ただし、単一スレッドであるため、入力値を受信するまで他の操作を実行できないため、効率は非常に低い.
スレッドの空き時間が解消されるため、CPU利用率が向上する.
2つのタスクは、2つのスレッドではなく1つのスレッドとして処理されます.
単一スレッドを使用すると、1つのタスクが完了した後に次のタスクを開始できますが、2つのスレッドを使用すると、タスクを同時に処理するように2つのタスクが交互に実行されます.
しかし、2つのスレッドがある場合、逆に、スレッド間の変換(Context Switching)が単一スレッドよりも長い時間を要することになる.
Context Switching
進行中のタスク(プロセスまたはスレッド)のステータスを保存し、次のタスクのステータスを取得します.
したがって、マルチスレッドは必ずしも良いわけではありません.場合によっては、単一スレッドでプログラミングしたほうがいいかもしれません.
単一スレッドを使用した2つのタスク
class SingleThreadExample {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 2000; i++) {
System.out.printf("%s", new String("-"));
// printf()와 new String()을 사용해서 고의로 속도를 늦췄음.
}
System.out.println("소요 시간1: " + (System.currentTimeMillis() - startTime));
for (int i = 0; i < 2000; i++) {
System.out.printf("%s", new String("|"));
}
System.out.println("소요 시간2: " + (System.currentTimeMillis() - startTime));
}
}
実行結果)(너무 길어서 앞부분 생략)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------소요 시간1: 21
(여기도 앞부분 생략)
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요 시간2: 32
Process finished with exit code 02つのタスクを完了するには32ミリ秒かかります
2つのマルチスレッド(2つ)を使用して2つのタスクを実行
class MultiThreadExample {
static long startTime = 0;
public static void main(String[] args) {
Thread1 t1 = new Thread1();
t1.start();
startTime = System.currentTimeMillis();
for (int i = 0; i < 2000; i++) {
System.out.printf("%s", new String("-"));
}
System.out.println("소요 시간1: " + (System.currentTimeMillis() - startTime));
}
}
class Thread1 extends Thread {
public void run() {
for (int i = 0; i < 2000; i++) {
System.out.printf("%s", new String("|"));
}
System.out.println("소요 시간2: " + (System.currentTimeMillis() - MultiThreadExample.startTime));
}
}
実行結果)(너무 길어서 앞부분 생략)----||||-----|||-------|||||----------------------||---------------|||--|||||--|||---------------------||||---------||---||----|||||---||||||||--||||------||--|||||||||||||-----||||||||||---------------------------||||||||||||||||---------|||||||||||||||||--------------||---|||-----||---||--|||||||||||||||||||||||||||----|||||||||||||||||||||------||||||||||---------------------------------------------------------------------------------------------------------------------------------------------------------------------------소요 시간2: 40
소요 시간1: 41
2つのタスクを完了するには41ミリ秒かかります8コアCPU環境でテストが行われているため、各コアはスレッドを1つ実行し、同時に2つのタスクを実行します.
「出力スクリーン」(console)という名前のリソースを共有するため、各スレッドがリソースを争っており、
-
と|
の出力が雑然と交互に現れる.結論:同じリソースを使用する2つのタスクを処理する場合、単一スレッドの速度はより速くなります.
📌 [注意]
パラレル(concurrent):単一カーネルで、タスクを複数のスレッドに分割し、順番に実行します.(物理的に同時に行われる操作ではありませんが、交代速度が速いので同時に行われているように見えます)
パラレル(Parallel):マルチコア環境では、タスクを複数のカーネルに分散し、各カーネルのスレッドを同時に処理します(実際には複数のタスクを同時に実行します).
📌 [注意]
実行中のサンプル・プロセスは、オペレーティング・システムのプロセス・スケジューラの影響を受けるため、サンプルの実行結果で測定される時間は毎回異なります.
プロセススケジューラは、プロセスの実行順序と実行時間を決定します.これは、毎回の状況に応じて異なり、スレッドに割り当てられる時間も固定されません.
異なるリソースを使用する2つのタスクを処理すると、マルチスレッドの速度が速くなります.
ex)ユーザからのデータ入力の受信、ファイルのネットワークへの転送、プリンタなどの外部機器とのI/O…
ユーザから入力値を受信して出力し、10から1秒ごとに数値を数えます.
class ThreadExample {
public static void main(String[] args) throws Exception{
String input = JOptionPane.showInputDialog("Enter any value");
System.out.println("Your input is: " + input);
for (int i = 10; i > 0; i--) {
System.out.println(i);
try {
Thread.sleep(1000); // 1초 동안 시간 지연
} catch (Exception e) {}
}
}
}
実行結果)Your input is: hello
10
9
8
7
6
5
4
3
2
1
入力と出力はまったく異なる操作であり、共有リソースはありません.ただし、単一スレッドであるため、入力値を受信するまで他の操作を実行できないため、効率は非常に低い.
class ThreadExample {
public static void main(String[] args) throws Exception{
Thread1 t1 = new Thread1();
t1.start();
String input = JOptionPane.showInputDialog("Enter any value");
System.out.println("Your input is: " + input);
}
}
class Thread1 extends Thread {
public void run() {
for (int i = 10; i > 0; i--) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (Exception e) {}
}
}
}
実行結果)10
9
8
7
6
Your input is: hello
5
4
3
2
1
今回は、2つのタスクがそれぞれ異なるスレッドで実行されるため、入力値が入力であれ出力であれ、数値カウントが行われます.スレッドの空き時間が解消されるため、CPU利用率が向上する.
Reference
この問題について(13-4. シングルスレッドとマルチスレッド), 我々は、より多くの情報をここで見つけました https://velog.io/@lhjun1028/13-4.-싱글-쓰레드와-멀티-쓰레드テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol