java에서 동기화 방법과 동기화 코드 블록의 차이 상세 설명

java에서 동기화 방법과 동기화 코드 블록의 차이 상세 설명
Java 언어에서 각 객체에는 자물쇠가 있습니다.라인은synchronized 키워드를 사용하여 대상의 자물쇠를 얻을 수 있습니다.synchronized 키워드는 방법 단계(굵은 입도 자물쇠)나 코드 블록 단계(세립도 자물쇠)에 적용됩니다.
문제의 유래:
이런 면접 문제를 봤어요.

// 
public synchronized void method1(){}

public void method2(){
 synchronized (obj){}
}

synchronized는 동기화 문제를 해결하는 데 사용됩니다. 여러 개의 스레드가 공유 데이터에 동시에 접근할 때 동기화를 하면 오류가 발생합니다. Java가 제공하는 해결 방안은 공유 데이터를 조작하는 문구를 한 시간에 한 스레드를 실행하면 실행 과정에서 다른 스레드가 들어오지 않고 실행할 수 있다는 것입니다.이 문제를 해결하다.여기서synchronized를 사용할 때 두 가지 방식이 있는데 하나는 위의 동기화 방법, 즉synchronized로 수식하는 방법이고 다른 하나는 제공하는 동기화 코드 블록이다.
여기는 왠지 이상하게 느껴진다. 이 두 가지 방법은 어떤 차이가 있을까. 기초를 잘 배우지 못해서 간단한 테스트를 했다. 코드는 다음과 같다.

public class SynObj {
  public synchronized void methodA() {
    System.out.println("methodA.....");
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public void methodB() {
    synchronized(this) {
      System.out.pritntln("methodB.....");
    }
  }

  public void methodC() {
    String str = "sss";
    synchronized (str) {
      System.out.println(    "methodC.....");
    }
  }
}


public class TestSyn {
  public static void main(String[] args) {
    final SynObj obj = new SynObj();

    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        obj.methodA();
      }
    });
    t1.start();

    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        obj.methodB();
      }
    });
    t2.start();

    Thread t3 = new Thread(new Runnable() {
      @Override
      public void run() {
        obj.methodC();
      }
    });
    t3.start();
  }
}

이 작은 코드 세션의 인쇄 결과는 다음과 같습니다.

methodA.....
methodC.....
//methodB 
methodB.....
이 코드의 인쇄 결과는,methodA......methodC…..곧 인쇄될 거야, methodB......시간이 좀 걸려서야 인쇄할 수 있습니다. 그러면 methodB는 왜 methodC처럼 빨리 호출되지 못합니까?
스레드 1 호출 방법 A를 시작한 후, 이어서 스레드 1을 5초 동안 휴면시킵니다. 이때 방법 C를 호출합니다. 방법 C는synchronized로 자물쇠를 잠그고 있습니다. 여기 자물쇠의 대상은str라는 문자열 대상입니다.그러나 방법 B는 다르다. 현재 대상this로 자물쇠를 넣는다. 방법 A가 방법에synchronized를 직접 넣는 것을 알아차린다. 이 자물쇠를 넣는 대상은 무엇일까?분명히 이 두 가지 방법은 자물쇠를 사용한다.
*이러한 결과로 우리는 이러한 동기화 방법이 무엇으로 자물쇠를 잠갔는지 알 수 있다. 스레드 1이 휴면하고 있기 때문에 자물쇠가 아직 풀리지 않았기 때문에 스레드 2는 5초 후에야 방법 B를 호출할 수 있다. 이로써 두 가지 자물쇠 메커니즘이 같은 자물쇠 대상, 즉 전 대상을 사용한다는 것을 알 수 있다.
또한 동기화 방법은 방법에 직접적으로synchronized를 가하여 자물쇠를 채운다. 동기화 코드 블록은 방법 내부에 자물쇠를 넣는 것이 뚜렷하다. 동기화 방법의 자물쇠 범위가 비교적 넓고 동기화 코드 블록의 범위가 작으면 작을수록 성능이 떨어진다. 일반적으로 자물쇠를 넣어 동기화를 해야 할 때 범위가 작을수록 좋은 것이 틀림없다. 이렇게 하면 성능이 더욱 좋다*.
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기