동기화 된 키워드는이 메소드가 잠겨 있음을 나타냅니다. 이 메소드를 실행할 때 어떤 스레드 (예 : 스레드 a)에 관계없이 다른 스레드 B (또는 C, D 등) 가이 메소드 (또는이 클래스의 다른 동기화 메소드)를 사용하고 있는지 확인해야합니다. 그렇다면 동기화 된 메소드를 사용 하여이 메소드를 실행하기 전에이 메소드를 실행하는 스레드 B (또는 C, D)를 기다리십시오. 그렇지 않은 경우 발신자를 잠그고 직접 실행하십시오. 동기화 된 방법과 동기화 된 블록의 두 가지 사용법이 포함됩니다.
멀티 스레드 동기화 메커니즘은 리소스를 잠그므로 동시에 하나의 스레드 만 작동 할 수 있고 동기화는 여러 스레드가 동시에 액세스 할 때 발생할 수있는 문제를 해결하는 데 사용됩니다.
동기화 메커니즘은 동기화 된 키워드를 사용하여 구현할 수 있습니다.
동기화 된 키워드가 메소드를 수정하면 메소드를 동기화 메소드라고합니다.
동기화 된 방법이 실행되거나 예외가 발생하면 잠금이 자동으로 해제됩니다.
다음은 동기화 된 키워드의 사용을 분석하는 예입니다.
1. 동기화 된 키워드의 분리 된 사용
예제 프로그램 1
공개 클래스 스레드 테스트 {public static void main (string [] args) {예제 = 새 예제 (); 스레드 T1 = 새로운 스레드 1 (예); 스레드 t2 = 새로운 스레드 1 (예); t1.start (); t2.start (); }} class example {public synchronized void execute () {for (int i = 0; i <10; ++ i) {try {thread.sleep (500); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "hello :" + i); }}} class stread1은 스레드 {private example example; public stread1 (예제 예) {this.example = example; } @override public void run () {example.execute (); }} Execute () 메소드에서 동기화 된 키워드를 준비할지 여부이 예제 프로그램의 실행 결과는 매우 다릅니다.
동기화 된 키워드가 추가되지 않으면 두 스레드는 Execute () 메소드를 동시에 실행하고 출력은 동시 그룹입니다.
동기화 된 키워드가 추가되면 0 ~ 9 세트가 먼저 출력되고 다음 세트가 출력되어 두 스레드가 순서대로 실행됨을 나타냅니다.
2. 여러 방법의 멀티 스레딩 상황
프로그램을 변경하고 예제 클래스에 다른 메소드 execute2 ()를 추가하십시오.
그런 다음 스레드 클래스 스레드 2를 작성하십시오. thread2의 run () 메소드는 execute2 ()를 실행합니다. 예제 클래스의 두 메소드는 동기화 된 키워드로 수정됩니다.
예제 프로그램 2
공개 클래스 스레드 테스트 {public static void main (string [] args) {예제 = 새 예제 (); 스레드 T1 = 새로운 스레드 1 (예); 스레드 T2 = 새로운 스레드 2 (예); t1.start (); t2.start (); }} class example {public synchronized void execute () {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "hello :" + i); }} public synchronized void execute2 () {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "세계 :" + i); }}} class stread1은 스레드 {private example example; public stread1 (예제 예) {this.example = example; } @override public void run () {example.execute (); }} class stread2 strule {private example example; public stread2 (예제) {this.example = example; } @override public void run () {example.execute2 (); }} 동기화 된 키워드가 제거되면 두 가지 메소드가 동시에 실행되며 상호 영향을 미치지 않습니다.
그러나 예제 서브 루틴에 작성된대로 두 가지 방법조차도 다음과 같습니다.
실행 결과는 항상 한 스레드의 출력과 다른 스레드의 실행입니다.
설명 :
객체에 여러 개의 동기화 된 메소드가 있고 스레드가 특정 순간에 동기화 된 메소드를 입력 한 경우, 다른 스레드는 메소드가 실행되기 전에 객체의 동기화 된 메소드에 액세스 할 수 없습니다.
결론적으로 :
동기화 된 키워드가 메소드를 수정하면 메소드를 동기화 메소드라고합니다.
Java의 각 객체에는 잠금 또는 모니터가 있습니다. 스레드가 객체의 동기화 된 메소드에 액세스하면 객체가 잠그고 다른 스레드는 객체의 동기화 된 메소드에 액세스 할 수 없습니다 (여기서는 동일한 방법이 아닌 모든 동기화 메소드를 나타냅니다). 이전 스레드가 실행 메소드를 완성하거나 예외를 던질 때까지는 객체의 잠금이 해제되어 다른 스레드가 객체의 동기화 된 메소드에 다시 액세스 할 수 있도록합니다.
현재 객체가 잠겨 있습니다. 다른 객체 인 경우 객체간에 제한 관계가 없습니다.
코드에서 두 번째 스레드 객체를 구성하려고 할 때 새 예제 객체가 전달되면 두 스레드의 실행 사이에는 제한이 없습니다.
3. 정적 동기화 방법을 고려하십시오
동기화 된 키워드 수정 된 메소드가 정적으로 수정되면, 비 정적 동기화 메소드가 객체를 잠그지 만 정적 메소드는 객체에 속하지 않고 클래스에 속하며이 메소드가있는 클래스의 클래스 객체를 잠그게합니다.
클래스가 얼마나 많은 개체가 생성하든 동일한 클래스 객체에 해당합니다.
예제 프로그램 3
공개 클래스 스레드 테스트 {public static void main (string [] args) {예제 = 새 예제 (); 스레드 T1 = 새로운 스레드 1 (예); // 다른 객체가 여기에 전달 되더라도 정적 메소드 동기화로 인해 여러 스레드가 동시에 실행되지 않습니다. 예 = 새 예제 (); 스레드 T2 = 새로운 스레드 2 (예); t1.start (); t2.start (); }} class example {public synchronized static void execute () {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "hello :" + i); }} public synchronized static void execute2 () {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "세계 :" + i); }}} class stread1은 스레드 {private example example; public stread1 (예제 예) {this.example = example; } @override public void run () {example.execute (); }} class stread2 strule {private example example; public stread2 (예제) {this.example = example; } @override public void run () {example.execute2 (); }} 따라서 정적 메소드 인 경우 (execute () 및 execute2 ()에 정적 키워드가 추가되어 있다면 다른 예제 객체가 두 스레드로 전달 되더라도 두 스레드는 여전히 서로 제한됩니다. 하나는 먼저 실행 된 다음 다음에 실행해야합니다.
결론적으로 :
동기화 된 메소드가 정적 인 경우 스레드가 메소드에 액세스 할 때 동기화 된 메소드가 위치한 객체가 아니라 동기화 된 메소드가 위치한 클래스에 해당하는 클래스 객체가 잠글 수 있습니다. Java에서는 클래스에 얼마나 많은 개체가 있더라도이 객체는 고유 한 클래스 객체에 해당합니다. 따라서 스레드가 동일한 클래스의 두 객체의 두 개의 정적 및 동기화 된 메소드에 액세스하면 실행 순서도 순차적입니다. 즉, 한 스레드가 메소드를 먼저 실행하고 다른 스레드는 실행이 완료된 후 시작됩니다.
4. 동기화 된 블록
동기화 블록 쓰기 방법 :
동기화 된 (개체) {} 이는 실행되면 객체 객체를 잠그는 것을 의미합니다. (이 객체는 모든 클래스의 객체가 될 수 있거나이 키워드를 사용할 수 있습니다).
이렇게하면 잠긴 객체를 직접 지정할 수 있습니다.
예제 프로그램 4
공개 클래스 스레드 테스트 {public static void main (string [] args) {예제 = 새 예제 (); 스레드 T1 = 새로운 스레드 1 (예); 스레드 T2 = 새로운 스레드 2 (예); t1.start (); t2.start (); }} class 예제 {private 객체 객체 = new Object (); public void execute () {synchronized (object) {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "hello :" + i); }}} public void execute2 () {synchronized (object) {for (int i = 0; i <20; ++ i) {try {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "세계 :" + i); }}}}} class stread1은 스레드 {private example example; public stread1 (예제 예) {this.example = example; } @override public void run () {example.execute (); }} class stread2 strule {private example example; public stread2 (예제) {this.example = example; } @override public void run () {example.execute2 (); }} 예제 프로그램 4에 의해 달성 된 효과는 예제 프로그램 2의 효과와 동일합니다. 두 스레드는 동시에 대신 순서대로 실행됩니다. 한 스레드가 실행되면 객체 객체가 잠겨 있고 다른 스레드는 해당 블록을 실행할 수 없습니다.
동기화 된 방법은 실제로 메소드의 모든 문을 동기화 된 블록으로 래핑 한 다음 동기화 된 블록의 괄호 안에이 키워드를 전달하는 것과 같습니다. 물론 정적 방법 인 경우 클래스 객체를 잠겨 있어야합니다.
아마도 메소드의 몇 줄만이 스레드 동기화 문제를 포함하므로 동기화 된 블록은 동기화 된 메소드보다 여러 스레드의 액세스를 더 세분화합니다. 동기화 된 블록의 컨텐츠 만 동시에 여러 스레드로 액세스 할 수 없으며,이 방법의 다른 문장은 동시에 동시에 여러 스레드에 의해 액세스 할 수 있습니다 (동기화 된 블록 전후 포함).
참고 : 동기화 된 데이터는 비공개 여야합니다.
결론적으로 :
동기화 된 방법은 거친 입자 동시 제어입니다. 특정 순간에 하나의 스레드 만 동기화 된 메소드를 실행할 수 있습니다.
동기화 된 블록은 세분화 된 동시성 제어로 블록의 코드 만 동기화합니다. 방법에 위치하고 동기화 된 블록 이외의 다른 코드는 동시에 여러 스레드로 액세스 할 수 있습니다.