CodeGym /Java Course /모듈 2: 자바 코어 /"wait-notify-notifyAll" 전략

"wait-notify-notifyAll" 전략

모듈 2: 자바 코어
레벨 12 , 레슨 7
사용 가능
그만큼

"안녕, 아미고!"

"wait-notify에 대해 자세히 알아보고 싶습니다. wait-notify 메서드는 스레드가 상호 작용할 수 있는 편리한 메커니즘을 제공합니다. 스레드 상호 작용을 위한 복잡한 고수준 메커니즘을 구축하는 데에도 사용할 수 있습니다."

"작은 예부터 시작하겠습니다. 웹 사이트를 통해 사용자가 만든 다양한 작업을 수행해야 하는 서버용 프로그램이 있다고 가정합니다. 사용자는 다양한 작업을 다른 시간에 추가할 수 있습니다. 작업은 리소스 집약적이지만 서버의 8 -코어 프로세서가 대처할 수 있습니다. 서버에서 작업을 어떻게 수행해야 합니까?"

"먼저 프로세서 코어 수만큼 작업자 스레드 그룹을 생성합니다. 각 스레드는 자체 코어에서 실행될 수 있습니다. 스레드는 서로 간섭하지 않으며 프로세서 코어는 가만히 앉아."

"두 번째로, 사용자의 작업이 추가될 대기열 개체를 생성합니다. 다른 유형의 작업은 다른 개체에 해당하지만 모두 실행할 수 있도록 Runnable 인터페이스를 구현합니다."

"작업 개체의 예를 들어 주시겠습니까?"

"확인 해봐:"

run() 메서드 호출 시 n 계승을 계산하는 클래스
class Factorial implements Runnable
{
 public int n = 0;
 public long result = 1;

 public Factorial (int n)
 {
  this.n = n;
 }

 public void run()
 {
  for (int i = 2; i <= n; i++)
   result *= i;
 }
}

"여태까지는 그런대로 잘됐다."

"좋습니다. 그럼 큐 개체가 어떻게 보여야 하는지 살펴보겠습니다. 그것에 대해 무엇을 말씀해 주시겠습니까?"

"스레드로부터 안전해야 합니다. 사용자로부터 태스크를 수신하는 스레드에 의해 태스크 오브젝트와 함께 로드된 다음 작업자 스레드가 태스크를 선택합니다."

"네. 그리고 한동안 작업이 부족하면 어떻게 할까요?"

"그러면 작업자 스레드는 더 있을 때까지 기다려야 합니다."

"그렇습니다. 이제 이 모든 것이 단일 대기열에 구축될 수 있다고 상상해 보십시오. 확인하십시오."

태스크 큐. 작업이 없으면 스레드는 잠들고 작업이 나타날 때까지 기다립니다.
public class JobQueue
{
 ArrayList jobs = new ArrayList();

 public synchronized void put(Runnable job)
 {
  jobs.add(job);
  this.notifyAll();
 }

 public synchronized Runnable getJob()
 {
  while (jobs.size() == 0)
   this.wait();

  return jobs.remove(0);
 }
}

" 작업 목록이 비어 있는지 확인하는 getJob 메서드가 있습니다 . 그런 다음 목록에 무언가가 나타날 때까지 스레드가 절전 모드(대기)로 전환됩니다."

"목록에 새 작업을 추가할 수 있는 put 메서드 도 있습니다 . 새 작업이 추가되자마자 notifyAll 메서드 가 호출됩니다. 이 메서드를 호출하면 getJob 메서드 내에서 잠든 모든 작업자 스레드가 깨어납니다.”

"대기 및 알림 방법이 어떻게 작동하는지 다시 기억할 수 있습니까?"

"대기 메서드는 뮤텍스 개체의 동기화된 블록 내부에서만 호출됩니다. 우리의 경우: this입니다. 또한 두 가지 일이 발생합니다.

1) 스레드가 잠들었습니다.

2) 스레드가 일시적으로 뮤텍스를 해제합니다(깨어날 때까지).

"그 후에 다른 스레드가 동기화된 블록에 들어가 동일한 뮤텍스를 획득할 수 있습니다."

" notifyAll 메서드는 뮤텍스 개체의 동기화된 블록 내에서만 호출할 수도 있습니다. 우리의 경우: this입니다. 또한 두 가지 일이 발생합니다."

1) 이 뮤텍스 개체를 기다리고 있는 모든 스레드가 깨어납니다.

2) 현재 스레드가 동기화된 블록을 종료하면 깨어난 스레드 중 하나가 뮤텍스를 획득하고 작업을 계속합니다. 뮤텍스를 해제하면 깨어난 다른 스레드가 뮤텍스를 획득하는 식입니다.

"버스와 매우 비슷합니다. 들어가서 요금을 지불하고 싶지만 운전사가 없습니다. 그래서 «잠이 듭니다». 결국 버스는 만원이지만 여전히 요금을 줄 사람이 없습니다. 그런 다음 운전사는 도착해서 «잘 부탁드립니다»라고 말합니다. 그리고 이것이 시작입니다..."

"흥미로운 비교군요. 그런데 버스가 뭡니까?"

"Julio가 설명했습니다. 21 세기에 사용되는 이상한 것들이있었습니다."

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION