2011-08-02 2 views
27

가능한 중복 :
Java SynchronizationJava에서 synchronized()/wait()/notifyAll()은 무엇을합니까?

내가 안드로이드 게임부터 책 을 읽고 있어요.

많은 부분이 synchronized()이지만 실제로 어떤 역할을하는지 이해하지 못합니다. 오랫동안 자바를 사용하지 못했고 멀티 스레딩을 사용해 본지 확실하지 않습니다.

캔버스 예제에서는 synchronized(this)을 사용합니다. 그러나 OpenGL ES 예에서는 stateChanged이라는 개체를 만든 다음 synchronized(stateChanged)을 사용합니다. 게임 상태가 변경되면 그것은 stateChanged.wait() 다음 stateChanged.notifyAll();

일부 코드를 호출

Object stateChanged = new Object(); 

    //The onPause() looks like this: 
    public void onPause() 
     { 
      synchronized(stateChanged) 
      { 
       if(isFinishing()) 
        state = GLGameState.Finished; 
       else 
        state = GLGameState.Paused; 

       while(true) 
       { 
        try 
        { 
         stateChanged.wait(); 
         break; 
        } catch(InterruptedException e) 
        { 
        } 
       } 
      } 
     } 
//The onDrawSurface looks like this: 
public void onDrawFrame(GL10 gl) 
    { 
     GLGameState state = null; 
     synchronized(stateChanged) 
     { 
      state = this.state; 
     } 

     if(state == GLGameState.Running) 
     { 

     } 

     if(state == GLGameState.Paused) 
     { 
      synchronized(stateChanged) 
      { 
       this.state = GLGameState.Idle; 
       stateChanged.notifyAll(); 
      } 
     } 

     if(state == GLGameState.Finished) 
     { 
      synchronized(stateChanged) 
      { 
       this.state = GLGameState.Idle; 
       stateChanged.notifyAll(); 
      } 
     } 
    } 

//the onResume() looks like this: 
synchronized(stateChanged) 
     { 
      state = GLGameState.Running; 
      startTime = System.nanoTime(); 
     } 
+4

(진실하게)이 질문을하기 전에 어디에서든지 검색 했습니까? 심지어 검색 스택 오버플로? –

+1

그래, 나 ... @ Joachim Sauver 그 질문 do not 대기 커버()/notify() –

+0

당신은 방금 wait()/notify()를 추가했다. 그것을 구축 라이브. –

답변

29
This Java Tutorial 아마 도움이 될 수 있습니다

는 당신이 이해 설명을 무엇 객체에 synchronized를 사용하면 않습니다.

object.wait()을 호출하면 해당 객체에 보관 된 잠금이 해제됩니다 (사용자가 synchronized(object)라고 말하면 발생합니다). 그리고 스레드를 고정시킵니다. 그런 다음 스레드는 object.notify() 또는 object.notifyAll()이 별도의 스레드에 의해 호출 될 때까지 대기합니다. 이러한 호출 중 하나가 발생하면 object.wait()으로 인해 중지 된 스레드를 계속 허용합니다. 이것은 이 아니고object.notify() 또는 object.notifyAll()이라는 스레드가 고정되어 대기중인 스레드로 제어권을 넘겨 준다는 의미이며, 대기중인 스레드는 이제 계속 진행할 수 있다는 것을 의미합니다.

+0

의미가 있습니다 ... 그래서 wait()를 사용하면 앱을 일시 중지하는 메인 스레드가 멈추고 OpenGL ES 중지. 그런 다음 OpenGL ES가 중지 된 후 렌더러 스레드가 주 스레드가 앱을 일시 중지하도록하는 notifyAll()을 호출합니다. –

1

하나 개의 스레드가 활성화 주어진 객체에 의해 동기화 된 블록 내에서 할 수있다. 호출 대기 중지는이 권한을 포기하고 다른 사람이 notify (all)()를 호출 할 때까지 현재 스레드를 비활성화합니다. 그런 다음 비활성 스레드는 동기화 된 블록에서 다시 실행하기를 시작하지만 원하는 모든 다른 스레드와 동일하게 처리됩니다. 어떻게 든 하나만 선택 (프로그래머가 어느 것에 영향을 미치거나 의존 할 수 없는지)합니다.

4

Java (Android 기반)는 여러 CPU 코어를 사용할 수있는 여러 스레드에서 실행할 수 있습니다. 멀티 스레딩은 자바가 정확히 두 개의 프로세스를 수행하도록 할 수 있음을 의미합니다. 한 번에 하나의 스레드에서만 작동하도록 보장해야하는 코드 블록이나 메서드 블록이있는 경우 해당 코드 블록을 동기화합니다.

Here is the official Java explanation from Oracle

이 동기화 당신은 단지 당신이 그것을 필요로 할 때 그것을 사용하려면 사용과 관련된 프로세서/IO 비용이 있음을 아는 것이 중요합니다. Java 클래스/메소드가 스레드로부터 안전한지 조사하는 것도 중요합니다. 예를 들어 ++ 증분 연산자는 스레드 안전을 보장하지 않지만 + = 1을 사용하여 값을 증가시키는 동기화 된 코드 블록을 쉽게 만들 수 있습니다.

44

synchronized 키워드는 변수 또는 메소드를 유지하는 데 사용됩니다. 스레드 -안전한. 당신과 같이 동기화 된 블록에 변수를 포장하는 경우 : 동기화 된 블록 내부의 로직 블록의 실행이 완료 될 때까지 기다립니다 실행되는 동안

synchronized(myVar) { 
    // Logic involing myVar 
} 

그런 다음 어떤 시도는 다른 스레드에서 myVar에의 값을 수정합니다. 블록에 들어가는 값이 해당 블록의 라이프 사이클을 통해 동일하게 유지됩니다.

+0

이것은 뮤텍스의 자바 버전이라고 말하는 것이 맞습니까? – Siavash

+1

@Siavash .NET에서? 예. –

1

java의 동기화 된 키워드는 2 가지로 사용됩니다.

첫 번째 의미는 임계 섹션이라고합니다. 즉, 한 스레드가 동시에 액세스 할 수있는 코드의 일부입니다. synchronized에 전달하는 객체는 어떤 종류의 이름 지정을 허용합니다. 하나의 코드가 synchronized(a)에서 실행되는 경우 synchronized(a)에있는 다른 블록에 액세스 할 수 없지만 synchronized(b)으로 코드 블록에 액세스 할 수 있습니다.

기타 문제는 스레드 간 통신입니다.스레드는 다른 스레드가이를 알릴 때까지 기다릴 수 있습니다. 대기 및 알림은 모두 synchronized 블록에 기록해야합니다.

아주 짧은 설명이었습니다. 멀티 스레딩에 대한 튜토리얼을 찾고 읽어 보는 것이 좋습니다. 이처럼 사용할

10

:

private synchronized void someMehtod() 

당신은 이러한 효과를 얻을 :

1. 첫째, 인터리브하기 위해 동일한 개체에 대한 동기화 방법이 호출에 수 없습니다. 한 스레드가 객체에 대해 동기화 된 메소드를 실행할 때 첫 번째 스레드가 객체로 완료 될 때까지 동일한 객체 블록 (실행 중단)에 대해 동기화 된 메소드를 호출하는 다른 모든 스레드.

둘째, 동기화 된 메소드가 종료 될 때 동일한 객체에 대한 동기화 된 메소드의 후속 호출과 자동적으로 happen-before 관계를 설정합니다. 이렇게하면 모든 스레드에서 객체 상태에 대한 변경 사항을 볼 수 있습니다. 당신은 코드의 동기화 된 블록을 사용할 때

당신은 유사한 효과를 얻을 ( here에서 촬영)

:

private void someMethod() { 
    // some actions... 

    synchronized(this) { 
    // code here has synchronized access 
    } 

    // more actions... 
} 

바와 같이 here

+0

확인. wait() 및 notify() 메서드는 어떻습니까? 어떻게 그들은 스레드에 간섭합니까? (원래 코드에 일부 코드를 추가했습니다) –