-
210423_3~4(멀티스레드)JAVA(Sol)(정리대기중..언젠가) 2021. 4. 23. 13:14
멀티스레드
1. 스레드 Thread : 어떤 로직이나 함수의 실행 단위.
a(){ }
(cpu자원)
a( ) 3번 호출 |---a()---|---a()---|---a()---| ===> 단일스레드 - 지금까지 사용법
각각의 함수가 자원을 독점
(cpu자원)
a( ) 3번 호출 |---a()---|
|---a()---|
|---a()---|
-- 동시성을 갖고 실행되는구간===> 멀티스레드(동시에 실행되는 것처럼 보임)
자원을 공유해서 사용한다
멀티스레드의 장점
[웹서버 - 하나의 클라이언트 처리시간 1초라고 가정]
동시에 1000명이 접속했다. 1000번째 사람의 앞에 999명의 즉999초 동안 기다려야 자신의 처리가 돌아온다
그런데, 멀티스레드가 되면, 웹서버가 자원을 돌아가면서 모든 클라이언트들에게 처리를 조금씩 돌아가면서
하게되므로 훨씬 빠른속도로 자신의 처리를 할 수가 있다.
돈이 되는 프로그램은 다 멀티다. 게임서버, db서버, 웹서버, 채팅 서버 ...~
적용방법
Runnable 인터페이스 적용하거나
|
Thread 클래스를 상속받아서 // Thread클래스는 Runnable을 구현한 구현 클래스이다.
|
MyThread { // 다중상속으로 Thread상속을 받을수없을때 Runnable 인터페이스를 적용한다.
↓
run( ) {
멀티로 구현하고자 하는 로직이나 함수를 run 메서드로 감싼다
}
}
기억!
Runnable Thread run() run(), start()가 있다. 결론 : 실행하려면 start() 가 포함하는 Thread 객체(인스턴스)를 만들어야한다
호출
MyThread mt = new MyThread ();
mt.run() ; <=== 호출불가. run()은 구현만 할 수 있고, 호출이 불가하다. 그래도 호출하면 단일스레드로 작동됨(주의
mt.start() ; <=== start() 라는 메서드로 호출한다.
원리
start( ) <==== jvm에 요청 등록 === >run() 호출
run( ) 은 jvm에 의해서 호출되므로 callback method라고 한다.
package chapter16; //스레드가 없는경우 class GenClass { private int num; //필드1 private String name; //필드2 public GenClass(String a, int b) { //생성자 name = a; num = b; } public void start() { //메서드1 for (int i = 0; i < num; i++) //로직 System.out.println(name + "." + i); } } public class NonThread { public static void main(String[] args) { GenClass t1 = new GenClass("first", 5); GenClass t2 = new GenClass("second", 5); GenClass t3 = new GenClass("third", 5); t1.start(); //단일스레드 jvm start()와 관련x t2.start(); t3.start(); } } //first.0 //first.1 //first.2 //first.3 //first.4 //second.0 //second.1 //second.2 //second.3 //second.4 //third.0 //third.1 //third.2 //third.3 //third.4
package chapter16; //멀티스레드 적용 class MyThread extends Thread { //스레드상속 private int num; private String name; public MyThread(String a, int b) { //생성자 name = a; num = b; } public void run() { // 멀티스레드구현 run()메서드 for (int i = 0; i < num; i++) System.out.println(name + ":" + i); } } public class ThreadTest1 { public static void main(String[] args) { MyThread t1 = new MyThread("first", 1000); //인스턴스1 MyThread t2 = new MyThread("second", 1000); //인스턴스2 MyThread t3 = new MyThread("third", 1000); //인스턴스3 t1.start(); // jvm start t2.start(); // 단 한번이라도 처리가 섞이면 멀티스레드이다 t3.start(); } } //second:0 //third:0 //first:0 //third:1 //second:1 //third:2 //first:1 //third:3 //second:2 //third:4 //....~~
package chapter16; //Runnable 인터페이스를 통한 멀티스레드 class ThreadOne implements Runnable { // Runnable 인터페이스상속//ThreadOne가 Runnable을 적용한 타겟클래스이다 private int num; private String name; public ThreadOne(String a, int b) { name = a; num = b; } public void run() { // 멀티스레드 구현 for (int i = 0; i < num; i++) System.out.println(name + ":" + i); } } public class TreadTest2 { public static void main(String[] args) { Thread t1 = new Thread(new ThreadOne(("first"), 1000)); // Thread는 Runnable을 구현한 클래스이다 // Runnable로 만들면 하위객체를 호출하지못하기때문에 형변환도해야한다 Thread t2 = new Thread(new ThreadOne(("second"), 1000)); Thread t3 = new Thread(new ThreadOne(("third"), 1000)); //생성자안의 파라미터에 Runnable의 인자(상속받은 ThreadOne)를 넣어서 사용하기때문 // =new Tread(new 러너블타겟()) ->new 러너블타겟()이 인자를 두개갖고있기때문에()가 또들어간것 t1.start(); t2.start(); t3.start(); } }
동시성 구간을 크게하기
앞의 사실에서 알수있듯이, 첫 스레드에서 잠시 쉬어갈때 다른 스레드가 시작된다.
그렇다면, 강제로 쉬게 하면 더 동시성 구간이 커지지 않을까?
그래서 sleep(ms);메서드 ms는 1/1000초 동안 쉬도록 하면 골고루 섞인다.
package chapter16; //동기화없는 경우 class RunThread extends Thread { public RunThread(String name) { super(name); //Thread의 String을 인자로 갖는 생성자 } public void run() { for (int i = 1; i <= 500; i++) { if (i % 50 == 0) System.out.println("Thread[" + getName() + "]:" + i); //getName은 상속받은 Thread에서 온것 } } } public class SchedulingTest1 { public static void main(String[] args) { Thread[] t = new RunThread[2]; //스레드 배열 t[0] = new RunThread("ONE"); t[1] = new RunThread("TWO"); t[0].start(); t[1].start(); } } //Thread[TWO]:50 //Thread[TWO]:100 //Thread[TWO]:150 //Thread[ONE]:50 //Thread[ONE]:100 //Thread[TWO]:200 //Thread[ONE]:150 //Thread[ONE]:200 //Thread[TWO]:250 //Thread[ONE]:250 //Thread[TWO]:300 //...~ 동시성이거의없다
package chapter16; //동기화를 처리한경우 class RunThread2 extends Thread { public RunThread2(String name) { super(name); } public void run() { for (int i = 1; i <= 500; i++) { if (i % 50 == 0) { System.out.println("Thread[" + getName() + "] :" + i); try { sleep(1); // 1/1000초에 한번 쉼 //동시성을 크게하기위함 System.out.println(""); } catch (Exception e) { } } } } } public class SchedulingTest2 { public static void main(String[] args) { Thread[] t = new RunThread2[3]; t[0] = new RunThread2("☆"); t[1] = new RunThread2("★"); t[2] = new RunThread2("◆"); t[0].start(); t[1].start(); t[2].start(); } } //Thread[★] :50 //Thread[☆] :50 //Thread[◆] :50 // //sleep발생구간 // //Thread[☆] :100 // //Thread[★] :100 //Thread[◆] :100 //Thread[★] :150 // // //Thread[◆] :150 //Thread[☆] :150 // // // //Thread[◆] :200 //Thread[★] :200 //Thread[☆] :200 // // //Thread[★] :250 // //Thread[◆] :250 //Thread[☆] :250 //...~
'JAVA(Sol)(정리대기중..언젠가)' 카테고리의 다른 글
210423_6(syncronized 동기화) (0) 2021.04.23 210423_5(동시스레드 우선순위) (0) 2021.04.23 210423_2(throws,throw) (0) 2021.04.23 210423_1(예외_Exception) (0) 2021.04.23 210422_7(예외처리try_catch_fianlly) (0) 2021.04.22