쓰레드 생성 방법
- Thread 클래스 상속
- Runnable 인터페이스 지정 후 Thread 에 넘겨주기
<멀티 쓰레드 사용>
1. Thread 클래스 상속 후 run()
메소드 재정의
start()
- Thread 클래스에 있는 start() 메소드는 JVM에 쓰레드를 스케줄링 해주는 역할을 한다.
run()
- 스케줄링 후 실행할 메소드는 run()이라는 메소드이다.
run()을 아예 재정의해서 우리가 원하는 작업으로 만들어 주어야 한다.
Thread.class의 run() 메소드
public void run() {
if (target != null) {
target.run();
}
}
Ex) Thread 상속 예제
public class Mythread extends Thread {
String data;
public Mythread(String data) {
this.data = data;
}
@Override
public void run() { //run() : 쓰레드가 실행되었을 때 호출하는 메소드(thread가 해야하는 작업)
for (int i = 0; i < 10; i++) {
System.out.print(data);
try {
Mythread.sleep(1000); //1000ms 만큼 잠시 흐름을 멈춘다.
} catch (InterruptedException e) { //잠시 멈추는 것이기 때문에, 오류로 인식
}
}
}
}
public class TreadMain {
public static void main(String[] args) {
Mythread t1 = new Mythread("!");
Mythread t2 = new Mythread("?");
/*
t1.run();
t2.run();
*
*
* run() 을 직접 호출하게 되면 컴퓨터가 스케줄링을 직접 하지 못하므로 단일 쓰레드나 마찬가지이다.
* 컴퓨터가 스케줄링을 거친 후 자신의 상황에 맞추어서 분할하여 작업할 수 있도록 start()를 사용해서 스케줄링을 시켜준다.
*/
//스케줄링으로 인해, t1과 t2의 메소드들이 동시에 진행되고 있음.
t1.start();
t2.start();
}
}
결과:
!?!?!??!?!?!!??!!??!
쓰레드를 사용하지 않으면 결과는 !!!!!!!!!!??????????
로 출력되어야하지만, 멀티쓰레드를 사용하게 됨으로써, 두개의 for문 메소드를 동시에 처리하게 되므로, 위와 같은 결과가 도출된다.
Runnable 인터페이스 지정후 Thread 에 넘겨주기
Thread 클래스를 상속받지 않고 run()을 재정의하지 않는다면, 내부에서 Runnable 타입의 target의 run()을 사용한다.
Runnable 인터페이스를 지정 받아서 run()만 재정의한 후 다른 Thread 객체 생성시 넘겨주고 그 객체의 start()를 사용하는 방식이다.
public class MyRunnable implements Runnable { String data; public MyRunnable(String data) { this.data = data; } @Override public void run() { for(int i = 0; i<10; i++) { System.out.print(data); try {Thread.sleep(1000);} catch (InterruptedException e) { } } }
}
```java
public class TreadMain {
public static void main(String[] args) {
MyRunnable r1 = new MyRunnable("앙");
MyRunnable r2 = new MyRunnable("웅");
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
결과:
앙웅앙웅웅앙웅앙앙웅웅앙앙웅앙웅웅앙웅앙
Main에 Thread 도 존재하기 때문에 t1, t2, Main의 멀티쓰레드의 작업으로 아래와 같은 결과가 나온다.
public class TreadMain {
public static void main(String[] args) {
MyRunnable r1 = new MyRunnable("앙");
MyRunnable r2 = new MyRunnable("웅");
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
System.out.println("멀티쓰레드 시작!");
t1.start();
t2.start();
System.out.println("프로그램 종료 ");
}
}
결과:
멀티쓰레드 시작!
프로그램 종료
앙웅앙웅앙웅웅앙앙웅웅앙앙웅앙웅웅앙웅앙
Main 쓰레드를 잠시 멈춰야 한다.
join()
- 해당 쓰레드 종료시까지 다른 쓰레드들 멈추는 메소드
public class MyRunnable implements Runnable {
String data;
public MyRunnable(String data) {
this.data = data;
}
@Override
public void run() {
for(int i = 0; i<10; i++) {
System.out.print(data);
try {Thread.sleep(1000);}
catch (InterruptedException e) {
}
}
}
}
public class TreadMain {
public static void main(String[] args) {
try {
t1.join(); //해당 쓰레드 종료시까지 다른 쓰레드들 멈추기.
t2.join();
} catch (InterruptedException e) {
}
System.out.println("\n프로그램 종료 ");
}
}
결과:
멀티쓰레드 시작!
앙웅웅앙앙웅웅앙앙웅웅앙웅앙앙웅앙웅웅앙
프로그램 종료
Ex) 동물 예제
public abstract class Animal {
String name;
public Animal(String name) {
super();
this.name = name;
}
abstract void MakeSomeNoise();
void move() {
System.out.println(this.name + ": 움직입니다.");
}
void sleep() {
System.out.println(this.name + ": 자고 있습니다.");
}
final void identity() {
System.out.println(this.name + ": 저는 동물입니다.");
}
}
public class Dog extends Animal implements Runnable{
public Dog(String name) {
super(name);
}
@Override
void MakeSomeNoise() {
System.out.println(super.name + ": 왈왈왈");
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
MakeSomeNoise();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
public class Ground {
public static void main(String[] args) {
Dog dg1 = new Dog("바둑이");
Dog dg2 = new Dog("방울이");
Dog dg3 = new Dog("달랑이");
Thread[] arrThread = {
new Thread(dg1),
new Thread(dg2),
new Thread(dg3)
};
System.out.println("강아지 세마리가 웁니다.");
for(int i = 0; i < arrThread.length; i++) {
arrThread[i].start();
}
//start() 를 호출한 뒤, 나중에 join을 해야함.
for(int i = 0; i < arrThread.length; i++) {
try {arrThread[i].join();}
catch (InterruptedException e) {}
}
System.out.println("강아지 세마리는 이제 울지 않습니다.");
}
}
강아지 세마리가 웁니다.
바둑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
바둑이: 왈왈왈
달랑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
방울이: 왈왈왈
달랑이: 왈왈왈
방울이: 왈왈왈
바둑이: 왈왈왈
달랑이: 왈왈왈
바둑이: 왈왈왈
방울이: 왈왈왈
바둑이: 왈왈왈
달랑이: 왈왈왈
방울이: 왈왈왈
강아지 세마리는 이제 울지 않습니다.
'Java > Java(base)' 카테고리의 다른 글
[Java] Generic 제네릭<> 클래스, 메소드, 인터페이스 (0) | 2021.12.05 |
---|---|
[Java]Object class toString(), equals(), hashcode() (0) | 2021.12.02 |
[Java] @Annotation, 어노테이션 (0) | 2021.12.01 |
[Java] Java API(Application Programming Interface) (0) | 2021.12.01 |
[Java] 예외처리 try-catch-finally / throw throws 차이점 및 예제 (0) | 2021.12.01 |