java 다중 루틴 프로그래밍의 Synchronized 키워드 상세 정보

본고는 JAVA 다중 스레드에서synchronized 키워드를 대상으로 잠그는 지식점을 소개한다.
대상 자물쇠란 synchronized가 어떤 대상에 자물쇠를 넣는 것이다.대상 자물쇠에 관하여 참고할 수 있습니다: 이 문장
분석
synchronized는 다음과 같은 방법으로 인스턴스를 수정할 수 있습니다.

public class MyObject {
  synchronized public void methodA() {
    //do something....
  }
여기,synchronized 키워드가 현재 대상을 잠그고 있습니다.이것도 대상 자물쇠라고 불리는 이유다.
왜 현재 대상을 잠갔습니까?methodA()는 실례적인 방법이기 때문에 methodA()를 실행하려면 대상이 필요합니다.방법 () 의 형식으로 호출 (obj.methodA (), obj는 My Object 클래스의 한 대상이며,synchronized는 obj라는 대상을 잠그는 것)
위의 코드도 이렇게 쓸 수 있다.

public class MyObject {

  public void methodA() {
    synchronized(this){
      //do something....
    }
  }
 

2. 특징
synchronized 키워드를 사용하여 동기화하는 뚜렷한 특징은 MyObject 클래스에 여러 개의synchronized 수식의 실례 방법을 정의할 때 여러 개의 라인이 같은 MyObject 클래스의 대상을 가지고 있으면 이런 방법은 동기화 방식으로만 실행할 수 있다는 것이다.즉, 하나의synchronized 수식 방법을 실행한 후에야 다른synchronized 수식 방법을 실행할 수 있다.
다음과 같습니다.

public class MyObject {

  synchronized public void methodA() {
    //do something....
  }

  synchronized public void methodB() {
    //do some other thing
  }
}

MyObject 클래스에는 두 가지 synchronized 수식 방법이 있습니다.

public class ThreadA extends Thread {

  private MyObject object;
// 
  @Override
  public void run() {
    super.run();
    object.methodA();
  }
}

스레드 A 실행 methodA()

public class ThreadB extends Thread {

  private MyObject object;
// 
  @Override
  public void run() {
    super.run();
    object.methodB();
  }
}

스레드 B 실행 methodB()

public class Run {
  public static void main(String[] args) {
    MyObject object = new MyObject();

    // A B  :object
    ThreadA a = new ThreadA(object);
    ThreadB b = new ThreadB(object);
    a.start();
    b.start();
  }
}

스레드 A와 스레드 B는 같은 MyObject 클래스의 대상object를 가지고 있기 때문에 이 두 스레드는 서로 다른 방법을 호출해야 하지만 동기화되어야 한다. 예를 들어 스레드 B는 스레드 A가 methodA() 방법을 실행한 후에methodB() 방법을 실행할 수 있다.
결론
위에서 알 수 있듯이 본고에서 말한 synchronized 자물쇠의 범위는 전체 대상이다.만약에 한 클래스에 여러 개의synchronized 수식의 동기화 방법이 있고 여러 라인이 이 클래스의 같은 대상(이 클래스의 같은 대상)을 가지고 있다면, 비록 서로 다른 방법을 사용하지만, 각 방법의 집행도 동기화된다.
만약 각 동기화 방법 사이에 공유 변수가 없거나 각 방법 간에 연락이 없지만 동기화만 실행할 수 있다면 이것은 효율에 영향을 줄 것이다.
넷째, 응용 프로그램 - synchronized를 사용하여 데이터의 불일치성으로 인해 더러운 데이터를 읽는 상황을 피한다
다음 예제:

public class MyObject {

  private String userName = "b";
  private String passWord = "bb";
  
  synchronized public void methodA(String userName, String passWord) {
    this.userName = userName;
    try{
      Thread.sleep(5000);
    }catch(InterruptedException e){
      
    }
    this.passWord = passWord;
  }

  synchronized public void methodB() {
    System.out.println("userName" + userName + ": " + "passWord" + passWord);
  }
}

methodA()는 사용자 이름과 암호를 변경합니다.현실에서 사용자 이름은 암호에 대응한다.
methodB()는 사용자 이름과 암호를 읽습니다.
만약methodB()가synchronized로 수식하지 않았다면, 스레드 A는 methodA()를 호출하여 7줄로 실행하고, 사용자 이름을 변경했습니다. 어떤 이유로 (예를 들어 9줄에서 잠을 잤다) CPU를 포기했습니다.
이때 스레드 B가 methodB () 를 실행하면 읽은 사용자 이름은 스레드 A가 변경한 사용자 이름 ("a") 이지만 비밀번호는 원래 비밀번호 ("bb") 입니다.스레드 A가 잠들어서 비밀번호를 바꿀 겨를이 없었기 때문이다.
단, methodB()가synchronized로 수식되면, 스레드 B는 스레드 A가 실행된 후(사용자 이름도 바뀌었고 비밀번호도 바뀌었음)를 기다려야만 methodB가 사용자 이름과 비밀번호를 읽을 수 있습니다.따라서 데이터의 불일치성으로 인한 더러운 읽기 문제를 피할 수 있다.
이상은 본고의 전체 내용입니다. 여러분이java프로그래밍을 배우는 데 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기