on
[Java] wait(), notifyAll() 를 활용한 스레드 동작 순서 제어
[Java] wait(), notifyAll() 를 활용한 스레드 동작 순서 제어
반응형
지난 포스팅에서 synchronized 키워드를 활용하여 동시성을 제어하는 걸 포스팅한적이 있다.
https://devkingdom.tistory.com/276
오늘은 좀더 나아가서 Thread의 순서를 제어할 수 있는 방법을 정리해 보려고한다.
제어하는 방식은 wait()와 notifyAll() 을 활용하는 것이다.
아래 코드를 보면 vote 메서드와 voteDone 메서드가 있다.
vote 메서드는 실행 스레드의 조건이 만족( 투표가 완료) 될 때까지 다른 스레드의 실행은 중단하고 기다리게 한다.(wait)
그리고 voteDone 메서드는 조건을 만족시킨 뒤에 다른 스레드를 깨우고 다시 실행을 하라고 알린다.(notifyAll)
package voting; public class VotingPlace { private String voter1; private String voter2; private boolean isEmptyPlace1; private boolean isEmptyPlace2; public VotingPlace() { this.isEmptyPlace1 = true; this.isEmptyPlace2 = true; } public synchronized void vote (String voter) throws InterruptedException { while ( (isEmptyPlace1 == false) && (isEmptyPlace2 == false)) wait(); if(isEmptyPlace1) { voter1 = voter; isEmptyPlace1 = false; System.out.println("투표소1 : " + voter1 + "님이 투표중 입니다."); } else if (isEmptyPlace2) { voter2 = voter; isEmptyPlace2 = false; System.out.println("투표소2 : " + voter2 + "님이 투표중 입니다."); } } public synchronized void voteDone(String voter) { if(voter.equals(voter1)) { voter1 = null; isEmptyPlace1 = true; System.out.println("투표소1 : " + voter + "투표 완료. 현재 비어있음"); } else if (voter.equals(voter2)) { voter2 = null; isEmptyPlace2 = true; System.out.println("투표소2 : " + voter + "투표 완료. 현재 비어있음"); } notifyAll(); } }
여기서 가장 중요한건 wait() 와 notifyAll() 메서드 모두 synchronized 처리되어 있는 메서드 내부에서 호출되어야한다는 것이다.
그리고 notifyAll() 말고 notify() 메서드도 있는데 notifyAll() 은 잠자고 있는 모든 스레드를 깨우고 notify()는 하나의 스레드만 깨운다. 여기서는 둘중 어느것을 써도 결과는 똑같다.
package voting; public class VoteThread implements Runnable { VotingPlace votingPlace; String voter; public VoteThread(VotingPlace votingPlace, String voter) { this.votingPlace = votingPlace; this.voter = voter; } @Override public void run() { try { votingPlace.vote(voter); Thread.sleep(3000); votingPlace.voteDone(voter); } catch (InterruptedException e) { e.printStackTrace(); } } }
아래 코드를 보면 투표소가 두개 있고 , 해당 투표소에서 투표를 하는 사람은 10명이다.
package voting; public class Vote { public static void main (String[] args) { VotingPlace votingPlace = new VotingPlace(); for(int i=1; i<= 10; i++) { Thread thread = new Thread(new VoteThread(votingPlace, "투표자"+i)); thread.start(); } } }
여기서 투표소가 빈 곳이 하나도 없으면 기다리다가 하나라도 빌렸다고 알려주면 대기하던 사람하나가 해당 투표소에서 투표를 하도록 되어 있다.
마지막으로 프로그램을 실행한 결과는 아래처럼 나온다.
반응형
from http://devkingdom.tistory.com/279 by ccl(A) rewrite - 2021-09-09 18:27:31