자바 병렬 synchronized 잠 금 내용 분석

synchronized 가 방법 에 사용 하 는 잠 금 은 무엇 입 니까?
잠 긴 것 은 현재 대상 의 현재 방법 입 니 다.다른 스 레 드 가 이 대상 에 접근 하 는 synchronized 방법 이나 코드 블록 이 막 히 지만 비 synchronized 방법 은 막 히 지 않 습 니 다.
더 럽 게 읽다
흔히 볼 수 있 는 개념다 중 스 레 드 에서 여러 스 레 드 에서 같은 대상 의 인 스 턴 스 변수 나 전체 정적 변 수 를 동시 방문 하 는 상황 이 발생 할 수 있 습 니 다.정확 한 동기 화 처 리 를 하지 않 으 면 발생 하 는 결 과 는'더러 운 읽 기'입 니 다.즉,얻 은 데 이 터 는 더욱 바 뀌 었 습 니 다.여기 부분 변 수 는 더러 운 읽 기 가 존재 하지 않 습 니 다.

public class ThreadDomain13
{
  private int num = 0;
  
  public void addNum(String userName)
  {
    try
    {
      if ("a".equals(userName))
      {
        num = 100;
        System.out.println("a set over!");
        Thread.sleep(2000);
      }
      else
      {
        num = 200;
        System.out.println("b set over!");
      }
      System.out.println(userName + " num = " + num);
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }
}
add 문자열"a"와 문자열"b"를 각각 두 스 레 드 로 작성 합 니 다.

public class MyThread13_0 extends Thread
{
  private ThreadDomain13 td;
  
  public MyThread13_0(ThreadDomain13 td)
  {
    this.td = td;
  }
  
  public void run()
  {
    td.addNum("a");
  }
}
public class MyThread13_1 extends Thread
{
  private ThreadDomain13 td;
  
  public MyThread13_1(ThreadDomain13 td)
  {
    this.td = td;
  }
  
  public void run()
  {
    td.addNum("b");
  }
}
주 함 수 를 써 서 각각 이 두 스 레 드 를 실행 합 니 다.

public static void main(String[] args)
{
  ThreadDomain13 td = new ThreadDomain13();
  MyThread13_0 mt0 = new MyThread13_0(td);
  MyThread13_1 mt1 = new MyThread13_1(td);
  mt0.start();
  mt1.start();
}
//       
a set over!
b set over!
b num = 200
a num = 200
정상 적 으로 는'a num=100'과'b num=200'을 인쇄 해 야 하 는데,지금 은'b num=200'과'a num=200'을 인쇄 한 것 이 스 레 드 보안 문제 다.우 리 는 어떻게 라인 안전 에 문제 가 있 는 지 생각해 볼 수 있다.
1.mt0 을 먼저 실행 하고 num 에 100 을 부여 한 다음 에"a set over!"를 출력 합 니 다.잠 을 자기 시작 하 다
2.mt0 이 잠 을 잘 때 mt1 이 실 행 됩 니 다.num 에 200 을 부여 한 다음 에"b set over!"를 인쇄 합 니 다.그리고"b num=200"을 인쇄 합 니 다.
3.mt1 잠 을 다 잤 습 니 다.mt0 의 num 과 mt1 의 num 은 같은 num 이기 때문에 mt1 은 num 을 200 으로 바 꾸 었 습 니 다.mt0 도 어 쩔 수 없습니다.그것 에 있어 서 num 은 100,mt0 만 코드 를 계속 실행 하고'a num=200'을 인쇄 할 수 있 습 니 다.
문제 가 발생 한 원인 을 분석 하면 해결 이 간단 합 니 다.addNum(String userName)방법 에 동기 화 를 하면 됩 니 다.
다 중 스 레 드 synchronized 키 워드 를 방법 에 추가 합 니 다.

public class ThreadDomain13
{
  private int num = 0;
  
  public synchronized void addNum(String userName)
  {
    try
    {
      if ("a".equals(userName))
      {
        num = 100;
        System.out.println("a set over!");
        Thread.sleep(2000);
      }
      else
      {
        num = 200;
        System.out.println("b set over!");
      }
      System.out.println(userName + " num = " + num);
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }
}
실행 결 과 를 보십시오.

a set over!
a num = 100
b set over!
b num = 200
여러 개체 여러 자물쇠
동기 화 된 상황 에서 main 함수 내의 코드 를 바 꿉 니 다.

public static void main(String[] args)
{
  ThreadDomain13 td0 = new ThreadDomain13();
  ThreadDomain13 td1 = new ThreadDomain13();
  MyThread13_0 mt0 = new MyThread13_0(td0);
  MyThread13_1 mt1 = new MyThread13_1(td1);
  mt0.start();
  mt1.start();
}
실행 결 과 를 보십시오.

a set over!
b set over!
b num = 200
a num = 100
여기 에는 중요 한 개념 이 하나 있다.키워드 synchronized 에서 얻 은 자 물 쇠 는 모두 대상 자물쇠 입 니 다.코드 나 방법(함수)을 자물쇠 로 하 는 것 이 아니 라 코드 나 방법(함수)을 자물쇠 로 하 는 것 입 니 다.사실 얻 은 것 도 대상 자물쇠 입 니 다.모니터(대상)가 다 를 뿐 입 니 다.어떤 라인 이 synchronized 키 워드 를 먼저 실행 하 는 방법 입 니까?어느 스 레 드 가 이 방법 에 속 하 는 대상 의 자 물 쇠 를 가지 고 있 고 다른 스 레 드 는 대기 상태 일 수 밖 에 없습니다.그러나 이 전 제 는 자물쇠 가 대상 자물쇠 라 고 하 는 이상 반드시 대상 과 관련 이 있 기 때문에 여러 스 레 드 가 같은 대상 에 방문 해 야 한 다 는 것 이다.
여러 스 레 드 가 여러 대상 에 접근 하면 자바 가상 머 신 은 여러 개의 자 물 쇠 를 만 들 고 위의 예 처럼 ThreadDomain 13 대상 두 개 를 만 들 면 2 개의 자 물 쇠 를 만 듭 니 다.두 스 레 드 가 서로 다른 자 물 쇠 를 가지 고 있 는 이상'잠 금 해제 대기'라 는 행위 에 제약 을 받 지 않 고 addNum(String userName)의 코드 를 각각 실행 할 수 있 습 니 다.
synchronized(this)가 잠 긴 것 은 무엇 입 니까?
잠 긴 것 은 현재 의 대상 이다.synchronized 블록 의 내용 이 실 행 된 후에 현재 대상 의 자 물 쇠 를 풀 어 줍 니 다.같은 시각 에 여러 개의 스 레 드 가 이 대상 에 접근 하면 차단 된다.
synchronized(object)가 잠 긴 것 은 무엇 입 니까?
잠 긴 것 은 object 대상 입 니 다.synchronized 블록 의 내용 이 실 행 된 후에 object 대상 의 자 물 쇠 를 풀 어 줍 니 다.같은 시각 에 여러 개의 스 레 드 가 이 대상 에 접근 하면 차단 된다.
여기 서 주의해 야 할 것 은 object 가 Integer,String 등 포장 클래스 일 때(new 에서 나 온 대상 제외)현재 대상 을 잠 그 지 않 고 스 레 드 를 막 지 않 습 니 다.포장 류 는 final 이기 때문에 수정 할 수 없고 수정 하면 새로운 대상 이 생 성 됩 니 다.따라서 한 스 레 드 가 수정 한 후에 다른 스 레 드 가 이 대상 의 자 물 쇠 를 가 져 올 때 이 대상 은 원래 의 대상 이 아니 기 때문에 다른 대상 의 자 물 쇠 를 가 져 오기 때문에 막 히 지 않 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기