Java에서 synchronized 키워드 수식 방법 동기화 용법 상세 설명

5591 단어 Javasynchronized
자바의 가장 기본적인 동기화 방식, 즉synchronized 키워드를 사용하여 방법의 병렬 접근을 제어하는 것이다.synchronized 키워드로 설명하는 모든 방법은 임계 구역입니다.Java에서 같은 객체의 임계 영역에는 같은 시간에 액세스할 수 있는 객체가 하나만 있습니다.
정적 방법에는 서로 다른 행위가 있다.synchronized 키워드로 설명하는 정적 방법, 동시에 하나의 실행 라인에만 접근할 수 있지만, 다른 라인에서는 이 대상의 비정적 synchronized 방법에 접근할 수 있습니다.이 점은 매우 신중해야 한다. 왜냐하면 두 라인은 한 대상의 두 가지 다른synchronized 방법, 즉 하나는 정적synchronized 방법이고 다른 하나는 비정적synchronized 방법이기 때문이다.만약 두 가지 방법이 모두 같은 데이터를 바꾸면 데이터가 일치하지 않는 오류가 발생할 것이다.
synchronized 블록의 구문은 다음과 같습니다.

public void method() 
{ 
  synchronized( ) 
   { 
   } 
 
} 
synchronized 키워드는 두 가지 용법이 있습니다. 하나는 방법의 정의에만 사용되고, 다른 하나는synchronized 블록입니다. 우리는synchronized를 사용하여 대상 변수를 동기화할 수 있을 뿐만 아니라,synchronizedl를 통해 동기화 클래스의 정적 방법과 비정적 방법을 동기화할 수 있습니다.
첫 번째: 비정적 방법의 동기화
자바 관련 문법에서 알 수 있듯이synchronized 키워드를 사용하여 방법을 정의하면 클래스에서synchroniezd 키워드로 정의한 정적 방법과 비정적 방법을 잠그지만 이것은 이해하기 어렵다. 만약synchronized 블록을 사용하여 이러한 효과를 얻으려면 왜 이런 효과가 발생했는지 이해하기 어렵지 않다. 만약synchronized를 사용하여 클래스의 모든 동기화 비정적 방법을 잠그면synchronized 블록의 매개 변수로 synchronized 블록에 전송하기만 하면 코드는 다음과 같습니다.

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 

 
위의 코드에 있는method1은synchronized 블록을 사용하고,method2 방법은synchronized 키워드로 방법을 정의합니다. 만약에 같은 테스트 실례를 사용할 때 이 두 가지 방법은 하나만 실행하면 다른 방법은 동기화 자물쇠를 얻지 못해 막힙니다.this를 synchronized 블록의 매개 변수로 사용하는 것 외에 Test도 사용할 수 있습니다.this는synchronized 블록의 매개 변수로 같은 효과를 냅니다.
내부 클래스에서synchronized 블록을 사용하는데,this는 내부 클래스만 표시하고, 외부 클래스(OuterClass)와 관계가 없습니다.그러나 내류 중의 비정태 방법과 외류의 비정태 방법도 동기화할 수 있다.이 클래스에 메서드 method3를 추가하면 Test의 두 메서드와 동기화할 수 있습니다. 코드는 다음과 같습니다.

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 

위 InnerClass의 method3 방법은 Test의 method1과 method2 방법과 같은 시간에 한 방법만 실행할 수 있습니다.
synchronized 블록이 정확하게 실행되었든지, 프로그램 오류로 인해synchronized 블록이 종료되었든지, 현재synchronized 블록이 가지고 있는 동기화 자물쇠는 자동으로 방출되기 때문에synchronized 블록을 사용할 때 동기화 자물쇠를 걱정할 필요가 없습니다.
2. 정적 방법의 동기화
정적 방법을 호출할 때 대상의 실례가 반드시 만들어지지 않기 때문에,this를 사용하여 정적 방법을 동기화할 수 없고, 클래스 대상을 사용하여 정적 방법을 동기화해야 한다.코드는 다음과 같습니다.

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 

정적 방법을 동기화할 때 클래스의 정적 필드 class를 사용하여 class 대상을 얻을 수 있습니다. 전례에서 method1과 method2 방법은 하나의 방법만 실행할 수 있습니다. class 필드를 사용하면 class 대상을 얻을 수 있고 실례적인 getClass () 방법을 통해 class 대상을 얻을 수 있습니다. 코드는 다음과 같습니다.

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 

 
위의 코드에서, 우리는public의 정적 대상을 통해 Test의 실례를 얻고, 이 실례의 getClass 방법을 통해class 대상을 얻는다. (한 종류의 모든 실례가 getClass 방법을 통해 얻은 것은 같은 Class 대상이라는 것을 주의하라.)우리도 class를 통해 다른 종류의 정적 방법을 동기화할 수 있다. 코드는 다음과 같다.

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 

 
주의:synchronized 블록을 사용하여 동기화 방법을 사용할 때 비정적 방법은this를 통해 동기화할 수 있고, 정적 방법은class 대상을 사용하여 동기화해야 하지만, 비정적 방법도class를 사용하여 정적 방법을 동기화할 수 있습니다.그러나 정적 방법에서this를 사용하여 비정적 방법을 동기화할 수 없습니다.이것은synchronized 블록을 사용하는 데 주의해야 합니다.
Note
synchronized 키워드는 응용 프로그램의 성능을 떨어뜨리기 때문에 병렬 상황에서 공유 데이터를 수정하는 방법에서만 사용할 수 있습니다.만약 여러 라인이 같은synchronized 방법에 접근한다면, 한 라인만 접근할 수 있고, 다른 라인은 기다릴 것입니다.만약 방법은synchronized 키워드를 사용하지 않았다면, 모든 스레드가 같은 시간에 이 방법을 실행할 수 있기 때문에 총 운행 시간이 낮아집니다.만약 하나의 방법이 상기 스레드에 호출되지 않는다는 것을 알고 있다면,synchronized 키워드로 설명할 필요가 없습니다.
synchronized에 의해 성명된 방법을 반복적으로 호출할 수 있습니다.루틴이 대상의 동기화 방법에 접근할 때, 이 대상의 다른 동기화 방법도 호출할 수 있으며, 실행 중인 방법도 포함하며, 이 방법의 접근권을 다시 얻을 필요가 없다.
우리는synchronized 키워드를 통해 코드 블록 (전체 방법이 아닌) 의 접근을 보호할 수 있습니다.이렇게 synchronized 키워드를 이용해야 합니다. 방법의 나머지 부분은synchronized 코드 블록 밖으로 유지하여 더 좋은 성능을 얻으십시오.임계 구역 (즉 같은 시간에 한 라인만 접근할 수 있는 코드 블록) 의 접근은 가능한 한 짧아야 한다.예를 들어 한 건물의 인원수를 가져오는 작업에서, 우리는synchronized 키워드만 사용하여 인원수에 대한 업데이트 명령을 보호하고, 다른 작업은 공유 데이터를 사용하지 않습니다.이렇게 synchronized 키워드를 사용할 때, 대상을 매개 변수로 인용해야 합니다.같은 시간에 이 synchronized 코드에 접근할 수 있는 라인이 하나밖에 없습니다.일반적으로 우리는 실행 중인 방법이 속한 대상을 인용하기 위해this 키워드를 사용합니다.

synchronized(this){
  //Java code
}

좋은 웹페이지 즐겨찾기