2011-02-25 3 views
0

코드 블록의 동기화는 많은 스레드가 액세스하기를 기다리는 동안에도 특정 코드가 한 스레드에서만 액세스된다는 것을 알았습니다.코드 블록에서의 동기화

우리는 run 메소드에서 스레드 클래스를 작성할 때 객체를 제공하여 동기화 된 블록을 시작합니다. 예를

class MyThread extends Thread{ 
    String sa; 
    public MyThread(String s){ 
     sa=s; 
    } 
    public void run(){ 
    synchronized(sa){ 
     if(sa.equals("notdone"){ 
      //do some thing on object 
     } 
    } 
    }  
} 
여기

우리는 우리가이 개체에 대한 동기화 코드의 특정 블록

+2

질문을 명확히 해주시겠습니까? – reef

+0

동기화 된 블록의 지점은 멀티 스레드 환경에서 휘발성 필드에 대한 스레드 안전 액세스입니다. 이 자습서는 도움이 될 수 있습니다 : http://www.csc.villanova.edu/~mdamian/threads/javamonitors.html –

+0

@reef sir 왜 이전에 거기에 있던 몇 가지 대답이 제거됩니다 ... – satheesh

답변

0

모든 스레드의 동기화를 제공하려고하는 방법 저런거의 필요가 무엇인지 동기화 블록에 사 객체를 준위한 것 현재 스레드가 작업을 마칠 때까지 기다린다. 예를 들어, 동기화하려는 컬렉션에 대한 읽기/쓰기 작업이있는 경우 유용합니다. 그래서 메서드 setget에 sychronized 블록을 쓸 수 있습니다. 이 경우 하나의 쓰레드가 정보를 읽는 중이라면, 읽거나 쓰길 원하는 다른 모든 쓰레드가 기다리지 않을 것이다.

+0

sir ..i understand what 동기화 된 블록을 수행 할 수 있지만 특정 동기화 된 블록에 대한 개체를 제공 할 필요가 무엇인지 얻지 못했습니다 – satheesh

1

나는

  • 오히려 실보다 Runnable를 확장 건의 할 것입니다.
  • 외부의 Runnable에 잠글 수 없습니다. 대신 내부 잠금을 사용할 수있는 메소드를 호출해야합니다.
  • 문자열을 자물쇠로 사용하는 것은 좋지 않습니다. "hi"와 "hi"는 잠금을 공유하지만 새로운 String ("hi")는 잠금을 의미하지 않습니다.
  • 스레드 수명 동안 다른 모든 스레드를 잠그고 있다면 왜 여러 스레드를 사용하고 있습니까?
+0

.. 내 코드가 문자열 코드에 대한 잠금 기능이 적절하지 않을 수 있습니다. 보통 동기화 된 방법에서는 어떤 객체도 제공하지 않습니다.하지만 동기화 된 블록에서 우리는 객체의 필요성을 알려줍니다. – satheesh

+0

복잡한 개체에서 많은 수의 잠금을 가질 수 있으며 각각에 대해 동기화 된 블록이 필요합니다. 때로는 클래스 외부에서도 잠글 수 있기 때문에 'this'를 잠그고 싶지 않은 경우가 있으므로 제공 한 Object를 잠글 수 있습니다. 일부 스레드 안전 컬렉션에는 스레드 안전 이터레이터가 없으므로 컬렉션을 잠글 필요가 있습니다. 반복 만하면됩니다. –

1

동기화 된 블록의 매개 변수 개체는 블록이 잠기는 개체입니다. 따라서 모두 개의 동기화 된 블록 이 같은 객체은 서로의 (그리고 같은 객체의 모든 동기화 된 메소드) 동시 실행을 제외시킵니다.

이 예

class ExampleA extends Thread() { 

    public ExampleA(Object l) { 
     this.x = l; 
    } 

    private Object x; 

    public void run() { 
     synchronized(x) {  // <-- synchronized-block A 
      // do something 
     } 
    } 
} 
class ExampleB extends Thread() { 

    public ExampleB(Object l) { 
     this.x = l; 
    } 

    private Object x; 

    public void run() { 
     synchronized(x) {  // <-- synchronized-block B 
      // do something else 
     } 
    } 
} 

Object o1 = new Object(); 
Object o2 = new Object(); 

Thread eA1 = new ExampleA(o1); 
Thread eA2 = new ExampleA(o2); 
Thread eB1 = new ExampleB(o1); 
Thread eB2 = new ExampleB(o2); 

eA1.start(); eA2.start(); eB1.start(); eB2.start(); 

이 그렇다면 이제 우리는 (클래스 ExampleAExampleB에서 A와 B) 두 개의 동기화 된 블록을 가지고, 우리는 두 개의 잠금 오브젝트 (O1과 O2)가 있습니다. 우리가 동시에 실행 보면

, 우리는 그것을 볼 수

  • A1은 A2 및 B1을 B2로 병렬로 실행될 수 있지만 수있다.
  • A2는 A1 및 B1과 병렬로 실행될 수 있지만 B2에는 실행되지 않습니다.
  • B1은 A2 및 B2와 병렬로 실행될 수 있지만 A1에는 실행되지 않습니다.
  • B2는 A1 및 B1과 병렬로 실행할 수 있지만 A2에는 수행 할 수 없습니다.

따라서 동기화는 동기화 블록 선택이 아닌 매개 변수 개체 인 에만 의존합니다.당신의 예에서


, 당신은이를 사용 : 당신은 당신이 그것을하고 작업을 비교하는 동안 사람이 다른 문자열에 sa 변수 인스턴스를 변경하는 것을 피하려고처럼

synchronized(sa){ 
    if(sa.equals("notdone"){ 
     //do some thing on object 
    } 
} 

이 보인다 -하지만 이것을 피하지는 않습니다. 문제의 객체가 보통 변수를 포함하는 오브젝트 (귀하의 경우 현재 MyThread 객체를 this로 연결할) 중 하나를해야한다, 또는 -

동기화는 객체에서 작동 변수에서 작동하지 않습니다 동기화 전용으로 사용되는 특수 오브젝트이며 변경되지 않습니다.

피터 레이 레이 (Peter Lawrey)가 말한 것처럼 문자열 객체는 모두 동일한 잠금 문자열에 대해 동일한 문자열 객체 (즉, 서로의 동기화 된 블록 제외)가 있기 때문에 일반적으로 동기화 잠금에 나쁜 선택입니다.)는 동일한 객체가 아니므로 동기화 된 블록을 다른 객체 또는 리터럴로 제외하지 않아 미묘한 버그가 발생할 수 있습니다.

0

그렇다면 블록이 동기화되는 객체의 기능은 무엇입니까?

모든 인스턴스 개체에는 모니터이 있습니다. 정상적인 실행에서이 모니터는 소유되지 않습니다.

동기화 된 블록을 입력하려는 스레드는 객체 모니터를 소유해야합니다. 그러나 한 번에 하나의 스레드 만 모니터를 가질 수 있습니다. 따라서 모니터가 현재 소유되지 않은 경우 스레드는 소유하고 코드의 동기화 된 블록을 실행합니다. 스레드는 동기화 된 블록을 벗어날 때 모니터를 해제합니다.

모니터가 현재 소유 된 경우 동기화 된 블록을 입력해야하는 스레드는 모니터가 해제 될 때까지 기다려야 소유권을 가져올 수 있고 블록을 입력 할 수 있습니다. 둘 이상의 스레드가 기다리고있을 수 있으며, 그렇다면 하나만 모니터의 소유권을 부여 받게됩니다. 나머지는 대기 상태로 돌아갑니다.

관련 문제