Java의 가장 기본적인 동기화 방법은 동기화 된 키워드를 사용하여 메소드의 동시 액세스를 제어하는 것입니다. 동기화 된 키워드로 선언 된 모든 방법은 중요한 섹션입니다. Java에서는 동일한 객체의 중요한 섹션 중 하나만 액세스 할 수 있습니다.
정적 방법마다 행동이 다릅니다. 동기화 된 키워드로 선언 된 정적 메소드는 하나의 실행 스레드에서만 액세스 할 수 있지만 다른 스레드는이 객체의 비 정적 동기화 된 메소드에 액세스 할 수 있습니다. 두 스레드가 동시에 두 개의 다른 동기화 된 메소드에 액세스 할 수 있기 때문에 이는 매우 신중해야합니다. 두 가지 메소드 모두 동일한 데이터를 변경하면 일관되지 않은 오류가 발생합니다.
동기화 된 블록의 구문은 다음과 같습니다.
public void method () {synchronized (expression) {}} 동기화 된 키워드에는 두 가지 사용이 있습니다. 하나는 메소드의 정의에만 사용되고 다른 하나는 동기화 된 블록입니다. 동기화 된 객체 변수를 동기화하기 위해 동기화 된 것을 사용할 수있을뿐만 아니라 동기화 된 L을 사용하여 클래스에서 정적 메소드와 비 정적 메소드를 동기화 할 수도 있습니다.
첫 번째 : 비 정적 방법의 동기화
Java 관련 구문에서 동기화 된 키워드를 사용하여 메소드를 정의하면 클래스의 Synchroniezd 키워드에 의해 정의 된 정적 메소드 및 비 정적 메소드가 잠겨 있지만 이해하기가 약간 어렵다는 것을 알 수 있습니다. 이러한 효과를 달성하기 위해 블록을 동기화하려면이 효과가 생성되는 이유를 이해하기가 어렵지 않습니다. 동기화 된 모든 동기화 된 비 정적 메소드를 클래스에서 잠그는 경우 동기화 된 블록으로 전달하려면 동기화 된 블록의 매개 변수로만 사용하면됩니다. 코드는 다음과 같습니다.
공개 클래스 테스트 {public void method1 () {synchronized (this) {}} public synchronized void method2 () {}} public class test {public void method1 () {synchronized (this) {}} public synchronized void method2 () {}} 위의 코드에서 Method1은 동기화 된 블록을 사용하고 Method2 메소드는 동기화 된 키워드를 사용하여 메소드를 정의합니다. 이 두 가지 메소드 중 하나가 실행되는 한 동일한 테스트 인스턴스를 사용하는 경우 동기화 잠금을 얻지 못했기 때문에 다른 방법이 차단됩니다. 이를 동기화 된 블록의 매개 변수로 사용하는 것 외에도 테스트를 사용할 수도 있습니다. 동일한 효과를 달성하기 위해 동기화 된 블록의 매개 변수로 사용할 수도 있습니다.
내부 클래스에서 동기화 된 블록을 사용하면 내부 클래스만을 나타내며 외부 클래스 (외부 클래스)와 관련이 없습니다. 그러나 내부 클래스의 비 정적 방법과 외부 클래스의 비 정적 방법도 동기화 될 수 있습니다. 내부 클래스에 메소드 메소드 3을 추가하면 테스트의 두 메소드와 동기화 할 수도 있습니다. 코드는 다음과 같습니다.
공개 클래스 테스트 {클래스 내부 클래스 {public void method3 () {synchronized (test.this) {}}} public class test {class InnerClass {public void method3 () {synchronized (test.this) {}}}} 상기 내부의 방법 3 방법과 방법 1 및 방법 2 테스트 방법은 동시에 하나의 방법 만 실행할 수 있습니다.
동기화 된 블록이 올바르게 실행 되든 프로그램 오류로 인해 예외로 인해 동기화 된 블록이 종료 되든, 현재 동기화 된 블록에서 보유한 동기화 잠금은 자동으로 해제됩니다. 따라서 동기화 된 블록을 사용할 때 동기화 잠금에 대해 걱정할 필요가 없습니다.
2. 정적 방법의 동기화
정적 메소드를 호출 할 때 객체 인스턴스가 반드시 생성 될 필요는 없으므로 정적 메소드를 동기화하는 데 사용할 수는 없지만 클래스 객체를 사용하여 정적 메소드를 동기화해야합니다. 코드는 다음과 같습니다.
public class test {public static void method1 () {synchronized (test.class) {}} public static synchronized void method2 () {}} public class test {public static void method1 () {synchronized (test.class) {}} public static synchronized void method2 () {}}정적 메소드를 동기화 할 때 클래스의 정적 필드 클래스를 사용하여 클래스 객체를 얻을 수 있습니다. 위의 예에서는 메소드 및 방법 2 메소드의 메소드 실행이 하나뿐입니다. 클래스 필드를 사용하는 것 외에도 인스턴스의 getClass () 메소드를 통해 클래스 객체를 얻을 수도 있습니다. 코드는 다음과 같습니다.
공개 수업 테스트 {공개 정적 테스트 테스트; public test () {test = this; } public static void method1 () {synchronized (test.getClass ()) {}} 공개 클래스 테스트 {public static test test; public test () {test = this; } public static void method1 () {synchronized (test.getClass ()) {}}}
위의 코드에서는 공개 정적 객체를 통해 테스트 인스턴스를 얻고이 인스턴스의 getClass 메소드를 통해 클래스 객체를 얻습니다 (클래스의 모든 인스턴스는 GetClass 메소드를 통해 얻어집니다). 또한 클래스를 통해 다른 클래스의 정적 메소드를 동기화 할 수 있습니다. 코드는 다음과 같습니다.
public class test1 {public static void method1 () {synchronized (test.class) {}}} public class test1 {public static void method1 () {synchronized (test.class) {}}}
참고 : 동기화 된 블록을 사용하여 메소드를 동기화하는 경우,이를 통해 비 정적 메소드를 동기화 할 수있는 반면, 정적 메소드는 클래스 객체를 사용하여 동기화해야하지만 클래스를 사용하여 비 정적 메소드를 동기화 할 수도 있습니다. 그러나 이것은 정적 메소드를 동기화하기 위해 정적 메소드에서 사용될 수 없습니다. 동기화 된 블록을 사용할 때주의를 기울여야합니다.
메모
동기화 된 키워드는 응용 프로그램의 성능을 저하 시키므로 동시 시나리오에서 공유 데이터를 수정 해야하는 메소드에서만 사용할 수 있습니다. 여러 스레드가 동일한 동기화 된 메소드에 액세스하면 한 스레드 만 액세스 할 수 있고 다른 스레드는 대기합니다. 메소드 선언이 동기화 된 키워드를 사용하지 않으면 모든 스레드가 메소드를 동시에 실행하여 총 실행 시간을 줄일 수 있습니다. 둘 이상의 스레드로 호출되는 것으로 알려진 경우 동기화 된 키워드를 사용하여 선언 할 필요가 없습니다.
동기화 된 방법을 재귀 적으로 호출 할 수 있습니다. 스레드가 객체의 동기화 메소드에 액세스하면 메소드에 대한 액세스를 다시 얻지 않고 실행 방법을 포함하여 객체의 다른 동기화 방법을 호출 할 수도 있습니다.
동기화 된 키워드를 통해 전체 방법이 아닌 코드 블록에 대한 액세스를 보호 할 수 있습니다. 동기화 된 키워드는 다음과 같이 사용해야합니다. 나머지 방법은 동기화 된 코드 블록 외부에 남아있어 성능을 향상시킵니다. 임계 섹션 (즉, 동시에 하나의 스레드에서만 액세스 할 수있는 코드 블록)에 대한 액세스는 가능한 한 짧아야합니다. 예를 들어, 건물에서 사람의 수를 얻는 작업에서 동기화 된 키워드를 사용하여 사람 수를 업데이트하기위한 지침을 보호하고 다른 작업이 공유 데이터를 사용하지 않도록합니다. 이러한 방식으로 동기화 된 키워드를 사용하는 경우 객체 참조를 들어오는 매개 변수로 사용해야합니다. 하나의 스레드만이 동기화 된 코드에 동시에 액세스 할 수 있습니다. 일반적으로, 우리는이 키워드를 사용하여 실행되는 메소드가 속한 개체를 참조합니다.
동기화 (this) {// java code}