본문 바로가기
Java

Thread (멀티 스레드)

by 임혁진 2023. 11. 30.

Thread의 정의와 이해

 

Thread의 사용방법은 2가지가 있다.

-Runnable 인터페이스 구현

-Thread 클래스 상속

 Thread의 주요 메소드

start() - Thread 클래스 실행

(static)currentThread() - 현재 스레드를 반환

getName() - 스레드 이름 반환

(static)sleep() - 스레드를 잠시 멈춤

yield() - 스레드 실행을 다른 스레드에게 양

join() -해당 스레드를 우선 실행 

 

Thread의 예제 -Runnable 인터페이스 구현

public class ThreadTest implements Runnable {

 

int num;

 

@Override

public void run() {

 

 

for(int i = 1; i <= 10; i++) {

 

Thread t = Thread.currentThread(); //현재동작되는 쓰레드 반환

if( t.getName().equals("A") ) { //현재 쓰레드의 이름을 받아옴

num++; //A쓰레드인 경우 num를 올린다

}

 

System.out.println("쓰레드이름:" + t.getName() + ", 합계:" + num);

 

//쓰레드 일시정지

try {

Thread.sleep(1000); //1초 일시정지

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

}

 

}

sleep -> throws 가 던져져있어 try-catch문으로 실행

 

쓰레드 예제 - 각자 돌아가는 쓰레드

public static void main(String[] args) {

 

//메인도 하나의 쓰레드로 동작을 합니다.

 

//쓰레드를 동작시키려면 Thread객체를 생성합니다.

 

//객체 2개, 쓰레드 2개 (각각 실행됨)

ThreadTest t = new ThreadTest();

ThreadTest t2 = new ThreadTest();

 

Thread thread = new Thread(t, "A");

thread.start();

 

Thread thread2 = new Thread(t2, "B");

thread2.start();

 

 

 

System.out.println("main쓰레드 종료");

 

 

}

}

 

쓰레드예제 - 하나의 객체에 같이 돌아가는 쓰레드

public class MainClass2 {

 

public static void main(String[] args) {

 

//객체 1개, 쓰레드는 2개 생성

ThreadTest t = new ThreadTest();

 

Thread thread = new Thread(t, "A");

Thread thread2 = new Thread(t, "B");

 

thread.start();

thread2.start();

 

 

System.out.println("main쓰레드 종료");

}

}

객체가 1개로  같은 스트림을 각각의 쓰레드가 같이 돌아간다

 

 

Thread의 예제 - Thread 상속 재정의

public class ThreadTest extends Thread {

 

int sum;

 

@Override

public void run() {

 

for(int i = 1; i <= 10; i++) {

 

if(getName().equals("A") ) {

sum++;

}

 

System.out.println("쓰레드이름:" + getName() + ", 합계:" + sum);

 

try {

sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

}

}

 

public class MainClass {

 

public static void main(String[] args) {

 

//Thread객체를 상속 받았으므로

ThreadTest t = new ThreadTest();

t.setName("A"); //쓰레드 이름 지정

t.start();

 

 

System.out.println("main스레드 종료");

 

}

}

 

Thread 클래스를 상속받았기에 run 메소드 재정의 뿐 아니라 다른 메소드도 쓸 수 있다.

또한 상속받았기에 Thread 객체를 따로 생성하지않고 ThreadTest 객체로 Thread 메소드를 쓸 수 있다.

 

 

동기화(Sync)

public class ThreadTest implements Runnable {

 

int num;

 

@Override

public synchronized void run() { //synchronized 만 적으면 된다.

 

for(int i = 1; i <= 10; i++) {

 

Thread t = Thread.currentThread(); //현재동작되는 쓰레드 반환

if( t.getName().equals("A") ) { //현재 쓰레드의 이름을 받아옴

num++; //A쓰레드인 경우 num를 올린다

}

 

System.out.println("쓰레드이름:" + t.getName() + ", 합계:" + num);

 

//쓰레드 일시정지

try {

Thread.sleep(1000); //1초 일시정지

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

}

 

}

메소드에 synchronized 만 적으면 쓰레드가 하나씩 순서대로 돌아간다..

public class MainClass {

 

public static void main(String[] args) {

 

//동기화 - 한번에 하나의 작업

//비동기화 - 한번에 여러개의 작업을 동시에 진행함

 

ThreadTest t = new ThreadTest();

 

Thread thread1 = new Thread(t, "A");

Thread thread2 = new Thread(t, "B");

 

thread1.start();

thread2.start();

 

System.out.println("main스레드 종료");

}

}