2013-12-18 2 views
1

동기화하는 동안 내재 된 메커니즘에 대해 더 깊이 이해하고 싶습니다. 나는 3 가지 예를 준비했다. 그리고 나는 그들 각각을 언급하는 질문을 가지고있다.스레드 : 동기화에 대한 깊은 이해


public class SyncExamples 
{ 

    SyncClass sync1, sync2; 


    public void execute1() 
    { 
     sync1 = new SyncClass(); 
     sync1.process(); 
    } 


    public void execute2() 
    { 
     sync2 = new SyncClass(); 
     sync2.process(); 
    } 



    class SyncClass 
    { 

     public synchronized void process() 
     { 

     } 
    } 
} 

있어서 프로세스() SyncClass의 동기화 : 그래서 여기 첫번째 예이다. 그러나 SyncExamples 클래스 SyncClass의 두 개의 서로 다른 객체이 만들어지면 둘 다 동시에 실행될 수 있으므로 실제로는 실행할 수 없습니다. 서로 다른 객체를 참조하므로 동기화가 없습니다. 맞아?

두 번째 예 :


public class SyncExamples 
{ 

    SyncClass sync1 = new SyncClass(); 


    public void execute1() 
    {  
     sync1.process(); 
    } 


    public void execute2() 
    {  
     sync1.process(); 
    } 




    class SyncClass 
    { 

     public synchronized void process() 
     { 

     } 
    } 
} 

그래서이 예에서 그들은 매우 같은 객체를 참조하십시오. 여기 뮤텍스가 있습니다. 동기화되어 있습니다. 그러나 나를 위해 가장 흥미로운 예를 들어 봅시다.


public class SyncExamples 
{ 

    SyncClass sync1 = new SyncClass(); 
    ReadWriteLock lock = new ReentrantReadWriteLock(); 


    public void execute1() 
    {  
     lock.writeLock().lock(); 
     sync1.process(); 
     lock.writeLock().unlock(); 
    } 


    public void execute2() 
    {  
     execute1(); 
    } 


    public void execute3() 
    {  
     sync1.process(); 
    } 


    public void execute4() 
    {  
     execute1(); 
    } 


    class SyncClass 
    { 

     public void process() 
     { 

     } 
    } 
} 

execute2()는 execute1()을 시작합니다. execute1()은 sync1.process()를 잠급니다. 이러한 이유 때문에 execute1()에 의해 sync1.process()가 잠금 해제 될 때까지 execute4()가 대기해야합니다. 하지만 execute3()은 어떨까요? execute1()을 참조하지 않고 잠금없이 sync1.process()를 직접 호출합니다. 그래서 execute1()에 의해 설정된 잠금은 execute3()에 유효하지 않습니까? 그게 맞습니까? 잠금은이 메소드가 잠금을 정의 할 때 execute1()을 참조하는 호출에만 유효합니다.

언젠가 나중에 추가 다음 예 :


public class SyncExamples 
{ 

    List list = new ArrayList(); 


    public void processList1() 
    {  
     synchronized(list) 
     { 
     } 
    } 


    public void processList2() 
    {  
     synchronized(list) 
     { 
     } 
    } 


    public void execute3() 
    {  
     processList1(); 
    } 


    public void execute4() 
    {  
     processList2(); 
    } 
} 

내가이 마지막 예를 명확히하고 싶습니다. 이제 동기화 할 목록이 있습니다. 메소드 processList1()은리스트를 동기화합니다 ... 메소드 processList2()도 메소드를 수행합니다. 그러나 동시에 실행할 수 있습니까? 을 동기화하면가 전체적으로 목록을 잠급니다 (즉, 모든 다른 방법의 다른 액세스를 의미 함)? 또는 특정 방법과 관련하여 만 사용할 수 있습니까? 나는 execute3()과 execute4()가 다른 메소드를 참조하기 때문에이 예제에서 동시에 실행될 수 있는지 이해할 수 없다. 동기화는 해당 블록에 대한 두 번째 액세스를 방지합니다. 그러나 목록에 대한 액세스 권한을 얻고 자하는 동기화 된 블록을 사용하는 여러 가지 방법이 있습니다. 따라서 processList1()이 목록을 잠그면이 목록이 processList2()에 대해 잠겨 있습니까? 또는이 lock이 processList2()에 유효하지 않은 이유는 다른 방법이기 때문입니다.

답변

0

첫 번째 질문 : 올바른
두 번째 경우 :

synchronized 블록은 인수 객체를 사용


대답 편집에 대한 올바른 : 네, 뮤텍스처럼
세 번째 질문을 역할 블록에 대한 잠금 (또는 더 나은 뮤텍스)으로. 따라서 두 스레드가 동일한 개체의 중요 섹션 synchronized에 도달하면 하나의 스레드 만 임계 섹션에 진입 할 수있게되고 다른 스레드는 임계 섹션에서 빠져 나올 때까지 대기합니다.

class SyncClass 
{ 
    public synchronized void process() 
    { 

    } 
} 

그래서, 질문에 대답

class SyncClass 
{ 
    public void process() 
    { 
     synchronized(this) 
     { 
      // whole body of process() inside this block 
     } 
    } 
} 

로 기록 될 수 있도록

synchronized 방법은 synchronized 블록의 단지 문법 설탕입니다

  • synchronized 잠급니다 list (또는 i로 사용되는 다른 객체 ts 인수)를 사용하는 것이 좋습니다. 코드의 어느 곳에서나 객체와 동기화 할 수 있으며 동기화 된 섹션은 포함 된 메소드/클래스 또는 호출 계층 구조와 상관없이 상호 배제로 실행됩니다.
  • processList1()processList2()은 동시에 실행되지 않습니다. 한 번에 하나만 실행할 수 있습니다. 이 코드는 synchonized 블록 외부에 코드가 없다고 가정합니다.
  • execute3()과 execute4()는 동시에 실행될 수 있지만 synchronized 섹션에 도달 할 때까지만 실행할 수 있습니다. 즉, 메서드를 호출하기 전에 processList1()processList2() 및 이러한 코드를 호출하면 동시에 실행할 수 있지만 synchronized 섹션의 코드는 동시에 실행할 수 없습니다.
+0

답해 주셔서 감사합니다. 방금 네 번째 예제를 추가했습니다. 이걸 좀 봐 줄래? 감사합니다 – Sheldon

+0

@Sheldon이 새로운 질문에 답변했습니다. –

+0

@rv이 문제를 해결해 주셔서 감사합니다. 그게 내가 알고 싶었던거야. – Sheldon

관련 문제