스레드의 동기화
두 개 이상의 스레드에 대하여 실행 순서를 맞추는 것을 말한다.
멀티 스레드 환경에서 여러 스레드가 공유 객체에 접근을 할때 다른 스레드에 의해서 예기치 않게 자원에 상태가 달라질 수 있다. 그렇기 때문에 스레드의 동기화가 필요하다. --> 실행 순서를 맞추며 공유 객체를 잠금할 수 있다.

위와 같이 보면 스레드 A가 동기화 메서드에 접근하면 다른 작업스레드에서는 접근할 수 없다.
해당 동기화 메서드가 실행이 끝나고 종료되면 그때서야 접근이 가능하다.
이러한 동기화 메서드를 만드는 코드는 아래와 같다.
public synchronized void method(){
}
//메서드 전체를 동기화 하지 않고 블록단위로 동기화하는 동기화블록
public void method2(){
synchronized(공유자원){
}
}
wait(), notify() 는 동기화와 관련되어있다 --> 이 메서드들은 Object 클래스의 메서드들이다.
wait()를 호출하여 해당 스레드가 일시정지 상태에 있을때 다른 스레드에서 notify()를 호출해주면 실행 대기상태에 다시 접어들 수 있다.
* 해당 메서드들은 동기화 블록, 동기화 메서드 안에서만 사용될 수 있다.
public class WorkObject {
public synchronized void methodA(){
Thread thread = Thread.currentThread();
notify(); //일단 다른 스레드를 실행대기로 만들어 놓는다.
try{
wait(); //자신 스레드를 이제 일시정지로 만든다.
}catch(InterruptException e){
}
}
}
wait함수에서 매개변수가 long 으로 들어가는데 매개변수가 있다면 해당 시간만큼 잠시대기이고,
매개변수가 없다면 무한정대기이다.
notify 메서드는 final로 선언이 되어있어 재정의가 불가능하다.
스레드의 안전 종료
가장 안전한 종료는 스레드의 run 메서드를 완전히 실행을 마치고 자동적으로 종료되는 것이다. 하지만
실행중인 스레드를 강제로 종료해야하는 상황이 있을 수 있다. 그렇지만 사용중인 스레드가 갑자기 종료되면 사용중이던
자원들이 불안전한 상태로 남겨질 수 있어 위험하다. 그렇기 때문에 안전하게 사용중이던 자원들을 정리하고
종료하는게 중요하다.
안전한 종료에는 주로 조건 이용 방법과 interrup 메서드가 사용된다.
조건 이용 방법
조건문으로 빈복 실행을 할 경우, 이 조건을 이용하여 스레드의 종료를 이끌 수가 있다.
public class TestThread extends Thread {
private boolean stop;
public void setStop(boolean stop){
this.stop = stop;
}
@Override
public void run(){
while(!stop){
//스레가 반복 실행할 코드
}
System.out.printlnt("사용한 리소스 정리");
System.out.printlnt("스레드 실행 종료");
} //종료된다.
}
public class StopThread{
public static void main(String[] args){
PrintThread printThread = new PrintThread();
printThread.start();
try{
Thread.sleeop(3000);
}catch(InterruptException e){
}
printThread.setStop(true); //안전 종료 , 리소스 정리
}
}
interrup
이 메서드는 스레드가 일시정지 상태에 있을때 InterruptedException 예외를 발생시킨다.
이것을 통해 예외처리를 이용하여 리소스를 정리하고 정상 종료가 가능해진다.
하지만 해당 메서드는 일시 정지상태일때만 InterruptedException 예외를 발생시킨다.
정상동작중에는 호출을 해봤자 InterruptedException 예외는 발생하지않는다.
그래서 sleep() 을 통해 명시적으로 일시정지를 시켜준 것이다. 하지만 이 sleep을 사용한다면 시스템적인 문제가 있다.
바로 딜레이가 생겨서 동작이 느려진다는 것이다.
이것에 대한 해결책으로 isInterrupted(); 메서드가 있다. 리턴값은 boolean으로 이 메서드는 interrup 메서드의 호출여부를 리턴한다. 호출했었다면 true 아니라면 false이다.
package Thread.exam01;
public class TestThread extends Thread{
@Override
public void run(){
while (true){
System.out.println("working");
if(Thread.interrupted()){
break;
}
}
System.out.println("리소스 정리");
}
}'Java' 카테고리의 다른 글
| [JAVA] Call By Value & Call By Reference (0) | 2025.09.15 |
|---|---|
| [JAVA] JVM 역할 및 내부구조 (1) | 2025.05.08 |
| [JAVA] 람다식 (0) | 2024.10.26 |
| [JAVA] 포장 클래스 (0) | 2024.10.20 |
| [JAVA] final 클래스와 final 메서드 (3) | 2024.10.18 |