일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- parseInt()
- 자바
- Interface
- 알고리즘
- 자바 재귀 조합
- jquery dom 계층 선택자
- 재귀
- inner class
- char to str
- 서로소
- 자바스크립트 이벤트중지
- 순열 재귀
- 조합 재귀
- 자바입출력
- 후위표기
- jquery 속성선택자
- jquery 이벤트 처리
- Java
- str to char array
- java 내부 클래스
- 재귀함수
- 순열코드
- java Collections.sort()
- jquery 필터선택자
- 알고리즘 그래프
- 상속
- 자바 순열 코드
- 자바 조합 재귀
- java lambda
- 자바스크립트 이벤트처리
- Today
- Total
유블로그
[Java] Thread 본문
반복문 1회에 1초라고 가정한다면
< Thread를 사용하지 않는 경우 > 반복문 5회 - A 작업 실행 1초 2초 3초 4초 5초 A -> A -> A -> A -> A |
< Thread를 사용한 경우 > 반복문 5회 - A 작업 실행 1초 2초 3초 4초 5초 A -> A -> A -> A -> A -> |
- main()을 실행하면 main thread가 동작한다. 만약 다른 thread가 실행되면 동시에 동작한다.
- main()이 종료되어도 실행 중인 다른 Thread가 모두 종료되어야 JVM의 실행이 종료된다.
- Thread 객체를 한 개만 만들고, start()를 두 번 호출하면 오류
- Thread 내에 또 다른 Thread 생성 가능. 하지만 공유 자원(변수/ 자료구조) 등에 대한 각별한 주의가 필요
쓰레드 사용법
1. Thread 클래스 상속
2. Runnable 인터페이스 implements -> Thread 클래스에 Runnable 객체를 주어 사용
/*
쓰레드 만드는 법 2가지
1. thread 클래스 상속
2. 인터페이스 runnable implements 하기
*/
class MyExThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
for(char c = 'a'; c <= 'z'; c++)
System.out.print(c + " ");
System.out.println();
}
}
}
class MyRunThread implements Runnable { // 쓰레드 아님!! 쓰레드처럼 동작할 수 있게 도와주는 것일뿐..
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
for(char c = 'A'; c <= 'Z'; c++)
System.out.print(c + " ");
System.out.println();
}
}
}
public class Test01 {
public static void main(String[] args) {
MyExThread t1 = new MyExThread();
MyRunThread t2 = new MyRunThread();
// t1.run(); // X
t1.start();
Thread t = new Thread(t2); // Thread 클래스에 Runnable 객체를 주면 쓰레드로 사용 가능
t.start();
}
}
< Thread.sleep() >
- static method
- 호출할 때, mili-second(1/1000초) 단위의 시간을 매개변수로 전달하면 그 시간만큼 실행을 중지했다다 다시 실행
- ex > 0.1 초 간 중지 후 다시 실행한다면, Thread.sleep(100);
< Thread.join() >
- 특정 thread 객체가 종료될 때까지 수행하던 일을 멈추고 특정 thread객체가 종료되면 다시 일을 수행한다.
class B extends Thread {
@Override
public void run() {
System.out.println("B 실행");
A a = new A();
a.start();
// 현재 쓰레드(B)가 특정 쓰레드(A)를 기다릴 때 사용
try {
a.join(3000); // () 안에 숫자 있으면 그만큼 대기, 없으면 무한정 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B : 3초 기다리다가 다시 실행");
}
}
class A extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + "초 지남");
}
}
}
public class Test04 {
public static void main(String[] args) {
System.out.println("JOIN 테스트");
B b = new B();
b.start();
}
}
< Thread.interrupt() >
- 대기 pool 에 있는 특정 Thread 객체를 방해하여 다시 runnable 상태로 이동시킬 수 있다.
public class AThread extends Thread {
@Override
public void run() {
try{
System.out.println("thread try start");
Thread.sleep(5000);
System.out.println("thread try end");
}catch(InterruptedException e){
System.out.println("thread interrupted raised");
}
System.out.println(num);
}
}
public class ThreadInterruptTest {
public static void main(String[] args) {
AThread t = new AThread(2020);
t.start();
try {
Thread.sleep(3000);
}catch(InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
System.out.println("Main Thread End!!");
}
}
< Thread.yield() >
- static method
- job 수행 중 지금 당장 job 수행할 필요가 없을 경우 호출, runnable 상태에 있는 다른 thread 들에게 수행 양보
- wait 상태로 가지 않고 runnable 상태로 이동하여 언제든 다시 경쟁을 이기고 running 상태가 되면, yield() 호출 이후 코드를 이어서 수행한다.
+ Thread.stop() 은 강제 종료를 통해서 이득보다 손해가 크므로 사용을 권장하지 않는다.
< synchronized >
concurrent 한 구조에서 여러 thread 간 공유자원에 대한 관리가 필수적이다.
어떤 thread가 자원에 대한 중요한 job을 실행하고 있는데 그 job이 종료되기 전에 다른 thread가 같은 자원에 접근하여 다른 job을 시작하면 오류가 생길 것이므로 다른 thread의 접근을 제한해야 한다.
중요한 job을 수행하는 경우 다른 thread의 접근을 제한하는 것을 동기화(synchronized)라고 한다.
방법
1. 중요 job 수행하는 Method 자체를 synchronized로 만들기.
시작부터 종료까지 다른 thread의 자원 접근을 막을 수 있다. 이 때 해당 thread가 공유자원에 대한 lock 을 소유했다
고 한다. job 이 끝나면 lock 을 반납한다.
2. Method 내 특정 블럭을 지정해서 synchronized 로 만들기.
method 전체 동기화보다 블록 동기화가 대체적으로 효율적이다.
- DeadLock
AThread가 A를 확보한 후 B를 요청하고, BThread가 B를 확보한 후 A를 요청하여 job이 진행되지 않는 경우를 말한다.
주로 중첩된 synchronized 구조에서 발생하므로 Thread를 구성하고 필요한 자원은 사용 후 즉시 반납할 수 있도록 synchronized block 을 최대한 작게 구성해야한다.
- wait()- notify() - notifyAll()
AThread가 공유자원에 대한 Lock을 소유하더라도 그 시점에 바로 중요한 일을 수행할 수 없으면 lock을 소유하지 않고 반납한다. 이를 wait()라고 한다.
AThread 가 자원 a를 반납하고 waiting pool 에서 대기하는 상태가 되면, 자원 a를 원하는 다른 thread들이 경쟁한다. 나중에 AThread가 다시 runnable 상태가 되면 다시 자원 a의 lock을 얻고 코드를 실행하려고 한다.
BThread가 자원 a를 얻어 필요한 작업을 수행했다면, a 자원을 기다리며 waiting pool에서 대기 중인 다른 thread들에게 이제 자원 a가 준비되었다고 알려야 하는데 그것을 notify(), notifyAll() 이라고 한다.
notify() 는 waiting pool에서 한 개의 thread에게만 알리는 것이고
notifyAll() 은 모든 thread들에게 알리는 것이다.
'Java' 카테고리의 다른 글
[Java] char to int / int to char / char to str / str to char array (0) | 2020.08.19 |
---|---|
[Java] JSON(Java Script Object Notation) (0) | 2020.08.18 |
[Java] Concurrent vs Parallel (0) | 2020.08.18 |
[Java] Lambda (0) | 2020.08.13 |
[Java] XML (0) | 2020.08.13 |