Java/Java

자바 스레드

code2772 2022. 10. 7. 15:26
728x90
반응형
1. 스레드(Thread)

프로세스
- 윈도우 작업 관리자에서 프로세스 탭에 올라와 있는 어플리케이션 하나
- 운영체제로부터 필요한 메모리를 할당받아 어플리케이션 코드를 실행

멀티 태스킹
- 두가지 이상의 작업을 동시(병렬작업)에 처리하는 것

스레드
- 하나의 프로세스 내부에서 독립적으로 실행되는 작업단위
- 운영채재애 의해 관리되는 하나의 작업 혹은 Task를 의미
- 다중 스레드 작업시에는 각 스레드끼리 정보를 주고 받을 수 있어 처리 과정의 오류를 즐일 수 있음
- 각 프로세스는 서로 정보를 주고 받을 수 없음
- JVM에 의해 하나의 프로세스가 발생, main() 안에 실행문들이 하나의 스레드

멀티 스레드
- 여러 스레드를 동시에 실행시키는 응용프로그램을 작성하는 기법
- 메모리 공유로 인한 시스템 자원 소모가 줄어듬
- 동시에 두가지 이상의 활용이 가능
- 서로 자원을 소모하다가 충돌이 일어날 가능성이 있음
- 코드가 난해해질 가능성이 있음

 

스레드 생성 방법 1 (Thread 클래스 상속)

    public class 클래스명 extends Thread {
        public void run(){
        스레드 객체가 start() 허출하면 실행될 문장;
        // 스레드는 start를 해야 호출이 가능하다.
        ...
        }
    }

    Thread 참조변수 = new 클래스명();
    참조변수.start();

✔ Thread 클래스는 start() 실행시 run() 메소드가 수행되도록 내부적으로 처리

 

public class PrintThread1 extends Thread {
    @Override
    public void run() {
        for(int i =0;i<10;i++){ // 스레드를 호출하면 실행하게 됨
            if(i%2==0){
                System.out.println("😁 PrintThread1 : "+i);
            }
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

 

스레드 생성 방법 2 (Runnable 인터페이스 구현)

    public class 클래스명 implements Runnable{
        public void run(){
         스레드 객체가 start() 허출하면 실행될 문장;
         ...
        }
    }

    Runnable 참조변수1 = new 클래스명();
    Thread 참조변수2 = new Thread(참조변수1);
    참조변수2.start();
public class PrintThread2 implements Runnable {
    @Override // Runnable을 이용한 스레드 생성 방법
    public void run() {
        for(int i =0;i<10;i++){
            if(i%2==0){
                System.out.println("🐱👤 PrintThread1 : "+i);
            }
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}
public class Thread1 {
    public static void main(String[] args) {
        Thread th1 = new PrintThread1();
        Runnable r1 = new PrintThread2();
        Thread th2 = new Thread(r1);
        Thread th3 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i =0;i<10;i++){
                    if(i%2==0){
                        System.out.println("🚀 PrintThread1 : "+i);
                    }
                    try{
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        });

        th1.start();
        th2.start();
        th3.start();
        for(int i =0;i<10;i++){
            if(i%2==0){
                System.out.println("🍊 main : "+i);
            }
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}
동기화(Synchronized)
- 멀티 스레드 프로세스에서는 다른 스레드의 작업에 영향을 미칠 수 있기 때문에 진행중인 작업이 다른
스레드레 간섭을 받지 않게 동기화가 필요

    메소드
    public synchronized 반환형 메소드명(매개변수1. 매개변수2 ..) {
        ...
    }

    문장
    synchronized(this){

    }

//    public synchronized void withdraw(int money){// synchronized 통해 동기화
//        this.money -= money;
//        System.out.println(Thread.currentThread().getName()+"가"+money+"출금");//현재 스레드를 알 수 있는 메소드/name은 이름
//        System.out.println("잔액 : " + this.money+"원");
//    }
@Override // 실 작업공간
public void run() {
    synchronized (this){// 전체가 코드가 동기화 되어 하나 씩 읽어가는 부분이 있다.
        for(int i=0;i<10;i++){
            withdraw(100000);
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

}

 

join()
- 스레드는 메인스레드가 종료되어도 다른 스레드는 백그라운드에서 동작하며 종료되지 않음
- join을 이용하면 다른 스레드가 종료될 때까지 메인스레드가 기다림

스레드 우선순위
- 스레드가 여러개인 경우 우선순위가 높은 스레드가 제어권을 많이 가지게 됨
- 으선순위는 1 ~ 10까지 int값으로 할당
- 기본 우선순위는 5
- 우선순위가 높은 스레드는 실행기회가 많이 주어짐

    MAX_PRIORITY : 가장 높은 순위, 10
    NORM_PRIORITY : 일반적인 순위, 5
    MIN_PRIORITY : 가장 낮은 순위, 1

yield()
- 다른 쓰레드에 자원사용율을 양보할 때 사용
- 우선순위가 낮은 스레드에게 다른 스레드가 해당 자원을 양보

 

public class Thread4 {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new PrioritySet(), "김사과");
        Thread thread2 = new Thread(new PrioritySet(),"김중과");
        Thread thread3 = new Thread(new PrioritySet(),"김대과");

        thread1.setPriority((Thread.MAX_PRIORITY));
        thread2.setPriority((Thread.NORM_PRIORITY));
        thread3.setPriority((Thread.MIN_PRIORITY));

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

 

public class PrioritySet extends Thread{
    PrioritySet(){}

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        int priority = Thread.currentThread().getPriority();
        System.out.println(name+" > "+priority);
    }
}

 

wait()
- 시간 값을 넣으면 주어진 시간 이후에 실행대기 상태로 전환
- 시간값을 넣지 않으면 일시정지

notify()
- wait()로 일시정지 중인 스레드 1개를 실행대기 상태로 전환

notifyAll()
- wait()로 일시정지 중인 모든 스래드를 실행대기 상태로 전환
반응형

'Java > Java' 카테고리의 다른 글

JAVA 네트워크  (0) 2022.10.20
자바 제네릭(Generic)  (0) 2022.10.12
자바 영어단어장  (0) 2022.10.07
자바 File 다루기  (1) 2022.10.07
자바 예외처리  (0) 2022.10.06