- 웹만들때 하이브리드 웹 만들때 말고는 잘 안씀
- 모바일, 채팅, 게임만들때 멀티쓰레드 많이 사용
- 멀티 쓰레드를 활용하는 방법
- 1. 하나의 클래스에 하나의 메소드를 적용하여 Thread를 활용
- 단, 메인에서 호출할 시 반복문을 이용
- 2. 각각의 Thread에 맞는 클래스를 별도로 구성(class 각각구성)하여 작동시키는 방식
- class abox extends Thread, class bbox extends Thread
- 멀티 쓰레드를 사용하는 이유
1. 여러개의 작업환경을 나누어서 빠르게 처리
2. CPU 사용율을 향상시켜서 자원을 보다 효율적으로 사용
3. 오류가 발생하더라도 해당 Thread외에는 정상 작동
- Web => 단일 쓰레드 -> Javascript 때문
[CLI]
React, Vue, Angular(병렬) => 멀티 쓰레드
[CDN]
React, Vue, Angular => 단일 쓰레드
1. 멀티쓰레드 - extends Thread
package method;
public class th1 {
public static void main(String[] args) {
//단일쓰레드 : aaa메소드 모두 실행 후 bbb 실행
th1_box tb = new th1_box();
// tb.aaa();
// tb.bbb();
//멀티쓰레드
int w = 0;
// mth1_box mtb = new mth1_box(); //밖에 두면 여러번 나옴
while(w < 100) {
mth1_box mtb = new mth1_box();
//멀티쓰레드 : 먼저 데이터 처리가 끝난 값을 출력
mtb.aaa(w);;
Thread th = new Thread(mtb); //Thread 클래스를 호출 후 run 메소드를 작동시키기 위하여 start()
//Thread에 즉시실행메소드가 있어서 바로 로드해서 사용
th.start(); //run 메소드를 각각의 Thread로 실행시키기 위함
//단일 쓰레드로 데이터를 출력시 무조건 순서대로 출력
// mtb.bbb(w);
w++;
}
}
}
class th1_box { //단일 쓰레드 형태 : 해당 메소드가 모두 실행 후 다음 메소드가 실행됨
public void aaa() {
int w = 0;
while(w < 100) {
System.out.println("a 메소드 : "+w);
w++;
}
}
public void bbb() {
int w = 0;
while(w < 100) {
System.out.println("b 메소드 : "+w);
w++;
}
}
}
//Thread 클래스를 상속받아야 사용 가능
class mth1_box extends Thread{ //멀티 쓰레드 형태
int no;
public void aaa(int w) {
this.no = w;
}
public void bbb(int w) {
this.no = w;
System.out.println(this.no);
}
@Override
public void run() { //멀티 쓰레드를 사용할 수 있도록 하는 메소드
try {
Thread.sleep(2000); //쓰레드를 일시정지 시키는 메소드 (1000 = 1초)
System.out.println(this.no);
}catch(Exception e) {
System.out.println("Thread에 문제가 발생하였습니다.");
}
}
}
- extends Thread : Thread 클래스 상속받아 Thread 사용
- run 메소드 : 멀티 쓰레드를 사용할 수 있게 함
- start() : run 메소드를 각각의 Thread로 실행시키기 위해 사용
2. 멀티쓰레드 - implements Runnable
package method;
public class th2 {
public static void main(String[] args) {
for(int f = 0;f<10; f++) {
Runnable ra = new th2_box(f);
Thread tr = new Thread(ra);
try {
// tr.sleep(1000); //sleep자리 여기 정석아님
tr.start();
}catch(Exception e) {
System.out.println("CPU 쓰레드에 문제가 발생하였습니다.");
}
}
}
}
//Runnable = 멀티 쓰레드 interface를 사용하는 방법
class th2_box implements Runnable{
int n = 0;
public th2_box(int z) { //interface에는 즉시실행없어서 만들어줌
this.n = z;
}
@Override
public void run() {
try {
Thread.sleep(1000); //sleep자리 정석 //1초후에 모든결과 바바박 -> 결제같은거 뻉글뺑글 돌아가는거
System.out.println(this.n);
}catch (Exception e) {
System.out.println("CPU 쓰레드에 문제가 발생하였습니다.");
}
}
}
- implements Runnable : Runnale 인터페이스를 사용해 Thread 사용
3. 예제
package method;
//각각의 클래스별로 멀티쓰레드를 작동 (Thread class)
public class th3 {
public static void main(String[] args) {
//각각의 class별로 Thread를 이용하여 작업을 분산
th3_abox a3 = new th3_abox();
Thread tr1 = new Thread(a3);
th4_abox a4 = new th4_abox();
Thread tr2 = new Thread(a4);
tr2.start();
tr1.start();
//덧셈을 나중에 호출했는데 덧셈이 더 빨리끝나서 출력에 덧셈이 먼저 나옴
//만약 하나가 오류가 나도 다른 쓰레드를 사용한 결과는 잘 출력됨
}
}
class th3_abox extends Thread { // 1Thread
int sum = 0;
@Override
public void run() {
for(int f = 1;f<21;f++) {
this.sum += f;
}
System.out.println("1 ~ 20을 모두 더한 값 : " + this.sum);
}
}
class th4_abox extends Thread{ //2Thread
long sum = 1L;
@Override
public void run() {
for(int f = 1;f<21;f++) {
this.sum *= f;
}
System.out.println("1 ~ 20을 모두 곱한 값 : " + this.sum);
}
}
😊응용문제
{10,65,33,22,19,31,26,87,94,21}
해당 원시 배열을 이용하여 멀티 쓰레드로 결과값을 출력하는 코드 작성
[결과]
짝수만 모두 곱한 값 출력
홀수만 모두 곱한 값 출력
모든 배열의 값을 더한 값 출력
내 코드
package method;
public class th4 {
public static void main(String[] args) {
th4_box1 b1 = new th4_box1();
Thread tr1 = new Thread(b1);
th4_box2 b2 = new th4_box2();
Thread tr2 = new Thread(b2);
th4_box3 b3 = new th4_box3();
Thread tr3 = new Thread(b3);
tr1.start();
tr2.start();
tr3.start();
}
}
class th4_box1 extends Thread { // 짝곱
int arr[] = { 10, 65, 33, 22, 19, 31, 26, 87, 94, 21 };
int result = 1;
@Override
public void run() {
for (int f = 0; f < this.arr.length; f++) {
if (this.arr[f] % 2 == 0) {
this.result *= this.arr[f];
}
}
System.out.println("짝수만 모두 곱한 값 : " + this.result);
}
}
class th4_box2 extends Thread { // 홀곱
int arr[] = { 10, 65, 33, 22, 19, 31, 26, 87, 94, 21 };
long result = 1;
@Override
public void run() {
for (int f = 0; f < this.arr.length; f++) {
if (this.arr[f] % 2 == 1) {
this.result *= this.arr[f];
}
}
System.out.println("홀수만 모두 곱한 값 : " + this.result);
}
}
class th4_box3 extends Thread { // 합
int arr[] = { 10, 65, 33, 22, 19, 31, 26, 87, 94, 21 };
int result = 0;
@Override
public void run() {
for (int f = 0; f < this.arr.length; f++) {
this.result += this.arr[f];
}
System.out.println("모든 배열의 값을 더한 값 : " + this.result);
}
}
선생님 코드
package method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//선생님코드
public class th4_t {
public static void main(String[] args) {
Integer data[] = { 10, 65, 33, 22, 19, 31, 26, 87, 94, 21 };
List<Integer> all = new ArrayList<Integer>(Arrays.asList(data));
t4_box1 th1 = new t4_box1(all);
t4_box2 th2 = new t4_box2(all);
t4_box3 th3 = new t4_box3(all);
Thread tr1 = new Thread(th1);
Thread tr2 = new Thread(th2);
Thread tr3 = new Thread(th3);
tr1.start();
tr2.start();
tr3.start();
// tr1.stop();//쓰레드 정지
}
}
class t4_box1 extends Thread {
List<Integer> all = null;
Integer mul = 1;
public t4_box1(List<Integer> all) { // 즉시실행으로 클래스배열로 변환된것을 받음
this.all = all;
}
@Override
public void run() {
for (Integer f : this.all) { // for문보다 훨씬 빠름 배열전용반복문
if (f % 2 == 0) {
this.mul = this.mul * f;
}
}
System.out.println("짝수만 모두 곱한 값 : " + this.mul);
}
}
class t4_box2 extends Thread {
List<Integer> all = null;
Long mul = 1L;
public t4_box2(List<Integer> all) {
this.all = all;
}
@Override
public void run() {
for (Integer f : this.all) {
if (f % 2 == 1) {
this.mul = this.mul * f;
}
}
System.out.println("홀수만 모두 곱한 값 : " + this.mul);
}
}
class t4_box3 extends Thread {
List<Integer> all = null;
Integer sum = 0;
public t4_box3(List<Integer> all) {
this.all = all;
}
@Override
public void run() {
for (Integer f : this.all) {
this.sum = this.sum + f;
}
System.out.println("모든 배열의 값을 더한 값 : " + this.sum);
}
}