Java 언어 키워드를 사용하여 메소드 또는 코드 블록을 수정하면 최대 한 스레드가 동시에 코드를 실행하도록 할 수 있습니다.
1. 두 개의 동시 스레드가 동일한 개체 객체에서 동기화 된 (이) 동기화 된 코드 블록에 액세스하면 한 번 이내에 하나의 스레드 만 실행할 수 있습니다. 다른 스레드는 코드 블록을 실행하기 전에 현재 스레드 가이 코드 블록을 실행할 때까지 기다려야합니다.
2. 그러나 한 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면 다른 스레드가 해당 객체의 비 동기화 된 (이) 동기화 코드 블록에 액세스 할 수 있습니다.
3. 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스 할 때 다른 스레드는 객체의 다른 모든 동기화 된 (이) 동기화 코드 블록에 대한 액세스를 차단하는 것이 특히 중요합니다.
4. 세 번째 예제는 다른 동기 코드 블록에도 적용됩니다. 즉, 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면이 객체의 객체 잠금을 얻습니다. 결과적으로, 다른 스레드는 객체 객체의 모든 동기 코드 부분에 대한 액세스가 일시적으로 차단됩니다.
5. 위 규칙은 다른 객체 잠금에도 적용됩니다.
예를 들어 :
1. 두 개의 동시 스레드가 동일한 개체 객체에서 동기화 된 (이) 동기화 된 코드 블록에 액세스하면 한 번 이내에 하나의 스레드 만 실행할 수 있습니다. 다른 스레드는 코드 블록을 실행하기 전에 현재 스레드 가이 코드 블록을 실행할 때까지 기다려야합니다.
package ths; public class stread1은 runnable {public void run () {synchronized (this) {for (int i = 0; i <5; i ++) {system.out.println (thread.currentthread (). getName () + "synchronized loop" + i); }}} public static void main (String [] args) {Thread1 t1 = new Thread1 (); 스레드 ta = 새 스레드 (t1, "a"); 스레드 tb = 새로운 스레드 (t1, "b"); ta.start (); tb.start (); }}결과:
동기화 된 루프 0
동기화 된 루프 1
동기화 된 루프 2
동기화 된 루프 3
동기화 된 루프 4
b 동기화 루프 0
b 동기화 된 루프 1
b 동기화 된 루프 2
b 동기화 된 루프 3
b 동기화 된 루프 4
2. 그러나 한 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면 다른 스레드가 해당 객체의 비 동기화 된 (이) 동기화 코드 블록에 액세스 할 수 있습니다.
package th; public class stread2 {public void m4t1 () {synchronized (this) {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ":" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}}} public void m4t2 () {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ":" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}} public static void main (String [] args) {Final Thread2 myt2 = new Thread2 (); 스레드 t1 = 새 스레드 (new Runnable () {public void run () {myt2.m4t1 ();}}, "t1"); 스레드 t2 = 새 스레드 (new Runnable () {public void run () {myt2.m4t2 ();}}, "t2"); t1.start (); t2.start (); }} 결과:
T1 : 4
T2 : 4
T1 : 3
T2 : 3
T1 : 2
T2 : 2
T1 : 1
T2 : 1
T1 : 0
T2 : 0
3. 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스 할 때 다른 스레드는 객체의 다른 모든 동기화 된 (이) 동기화 코드 블록에 대한 액세스를 차단하는 것이 특히 중요합니다.
// Thread2.m4t2 () 메소드를 수정하십시오 : public void m4t2 () {synchronized (this) {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ":" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}}}결과:
T1 : 4
T1 : 3
T1 : 2
T1 : 1
T1 : 0
T2 : 4
T2 : 3
T2 : 2
T2 : 1
T2 : 0
4. 세 번째 예제는 다른 동기 코드 블록에도 적용됩니다. 즉, 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면이 객체의 객체 잠금을 얻습니다. 결과적으로, 다른 스레드는 객체 객체의 모든 동기 코드 부분에 대한 액세스가 일시적으로 차단됩니다.
// 다음과 같이 Thread2.m4t2 () 메소드를 수정합니다. public synchronized void m4t2 () {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ":" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}} 결과:
T1 : 4
T1 : 3
T1 : 2
T1 : 1
T1 : 0
T2 : 4
T2 : 3
T2 : 2
T2 : 1
T2 : 0
5. 위의 규칙은 다른 객체 잠금에도 적용됩니다.
패키지 th; public class stread3 {클래스 내부 {private void m4t1 () {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ": inner.m4t1 () =" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}} private void m4t2 () {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ": inner.m4t2 () =" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}}} private void m4t1 (내부 내부) {synchronized (내부) {// 객체 잠금 내부를 사용합니다 .m4t1 (); } private void m4t2 (내부 내부) {inner.m4t2 (); } public static void main (String [] args) {Final Thread3 myt3 = new Thread3 (); 최종 내부 내부 = myt3.new inner (); 스레드 t1 = 새 스레드 (new Runnable () {public void run () {myt3.m4t1 (내부);}}, "t1"); 스레드 t2 = 새 스레드 (new Runnable () {public void run () {myt3.m4t2 (내부);}}, "t2"); t1.start (); t2.start (); }}결과:
스레드 T1은 내부의 객체 잠금을 얻지 만 스레드 T2는 동일한 내부에서 비동기 부품에 액세스하기 때문입니다. 따라서 두 스레드는 서로를 방해하지 않습니다.
T1 : 내부 .m4t1 () = 4
T2 : 내부 .m4t2 () = 4
T1 : 내부 .m4t1 () = 3
T2 : 내부 .m4t2 () = 3
T1 : 내부 .m4t1 () = 2
T2 : 내부 .m4t2 () = 2
T1 : 내부 .m4t1 () = 1
T2 : 내부 .m4t2 () = 1
T1 : 내부 .m4t1 () = 0
T2 : 내부 .m4t2 () = 0
이제 내부 앞에 동기화를 넣습니다 .m4t2 () :
개인 동기화 된 무효 M4T2 () {int i = 5; while (i--> 0) {system.out.println (thread.currentthread (). getName () + ": inner.m4t2 () =" + i); try {thread.sleep (500); } catch (InterruptedException IE) {}}}결과:
스레드 T1과 T2는 동일한 내부 물체의 두 개의 관련이없는 부분에 액세스하지만, T1은 먼저 내부에 객체 잠금을 얻기 때문에 T2의 내부에 대한 액세스가 내부의 동기화 메소드이기 때문에 T2의 내부에 대한 액세스가 차단되기 때문입니다.
T1 : 내부 .m4t1 () = 4
T1 : 내부 .m4t1 () = 3
T1 : 내부 .m4t1 () = 2
T1 : 내부 .m4t1 () = 1
T1 : 내부 .m4t1 () = 0
T2 : 내부 .m4t2 () = 4
T2 : 내부 .m4t2 () = 3
T2 : 내부 .m4t2 () = 2
T2 : 내부 .m4t2 () = 1
T2 : 내부 .m4t2 () = 0
Article 2:
동기화 된 키워드, 여기에는 동기화 된 메소드와 동기화 된 블록의 두 가지 사용법이 포함됩니다.
1. 동기화 된 방법 : 메소드 선언에 동기화 된 키워드를 추가하여 동기화 된 메소드를 선언합니다. 좋다:
Public Synchronized Void AccessVal (int NewVal);
동기화 된 메소드 제어 클래스 멤버 변수에 대한 액세스 : 각 클래스 인스턴스는 잠금에 해당하며 각 동기화 된 메소드는 실행되기 전에 메소드를 호출하는 클래스 인스턴스의 잠금을 얻어야합니다. 그렇지 않으면, 그것이 속한 실이 차단됩니다. 메소드가 실행되면 잠금을 독점적으로 차지합니다. 잠금은 메소드에서 돌아올 때까지 해제되지 않습니다. 차단 된 스레드는 잠금을 얻고 실행 가능 상태를 다시 입력 할 수 있습니다. 이 메커니즘은 동시에, 각 클래스 인스턴스에 대해 동시에 동기화 된 모든 멤버 기능 중 하나가 실행 가능 상태에 있음을 보장합니다 (대부분 클래스 인스턴스에 해당하는 잠금을 얻을 수 있기 때문에 클래스 멤버 변수의 액세스 충돌을 효과적으로 피할 수 있기 때문에 클래스 멤버 변수에 액세스 할 수있는 모든 방법이 선언 된 경우).
Java에서 클래스 인스턴스뿐만 아니라 각 클래스는 잠금에 해당하므로 클래스의 정적 멤버 기능을 클래스의 정적 멤버 변수에 대한 액세스를 제어하기 위해 동기화 된 것으로 선언 할 수 있습니다.
동기화 된 방법의 단점 : 동기화 된 대규모 방법을 선언하면 효율성에 큰 영향을 미칩니다. 일반적으로 스레드 클래스의 메소드 run ()이 동기화 된 것으로 선언 된 경우, 스레드의 수명 내내 실행 되었으므로이 클래스의 동기화 된 메소드에서 성공하지 못하게됩니다. 물론 클래스 멤버 변수에 액세스하는 코드를 특수 메소드에 넣고 동기화 된 것으로 선언하고 주요 방법으로 호출 하여이 문제를 해결할 수 있지만 Java는 더 나은 솔루션, 즉 동기화 된 블록을 제공합니다.
2. 동기화 된 블록 : 동기화 된 키워드를 통해 동기화 된 블록을 선언합니다. 구문은 다음과 같습니다.
동기화 (syncobject) {// 액세스 제어를 허용하는 코드}} 동기화 된 블록은 코드가 실행되기 전에 객체 syncobject의 잠금을 얻어야하는 코드 블록입니다. 특정 메커니즘은 위에서 설명한 것과 동일합니다. 모든 코드 블록을 타겟팅 할 수 있고 잠긴 객체를 언제든지 지정할 수 있으므로 더 유연합니다.
동기화 된 (this) <br /> 1에 대한 일부 이해 . 두 개의 동시 스레드가 동일한 개체에서 동기화 된 (이) 동기화 된 코드 블록에 액세스하면 한 번 이내에 하나의 스레드 만 실행할 수 있습니다. 다른 스레드는 코드 블록을 실행하기 전에 현재 스레드 가이 코드 블록을 실행할 때까지 기다려야합니다.
2. 그러나 한 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면 다른 스레드가 해당 객체의 비 동기화 된 (이) 동기화 코드 블록에 액세스 할 수 있습니다.
3. 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스 할 때 다른 스레드는 객체의 다른 모든 동기화 된 (이) 동기화 코드 블록에 대한 액세스를 차단하는 것이 특히 중요합니다.
4. 세 번째 예제는 다른 동기 코드 블록에도 적용됩니다. 즉, 스레드가 객체의 동기화 된 (이) 동기화 코드 블록에 액세스하면이 객체의 객체 잠금을 얻습니다. 결과적으로, 다른 스레드는 객체 객체의 모든 동기 코드 부분에 대한 액세스가 일시적으로 차단됩니다.
5. 위 규칙은 다른 객체 잠금에도 적용됩니다.
자바에서 동기화 된 사용 방법
예를 들어, 물체는 큰 집과 같고 문은 항상 열려 있습니다. 집에는 많은 방이 있습니다 (즉, 방법).
이 객실은 잠겨 있습니다 (동기화 된 방법). 잠금되지 않았습니다 (정상 방법). 문에는 열쇠가있어 모든 잠긴 방을 열 수 있습니다.
또한 객체 방법을 호출하려는 모든 실을이 집의 방에 들어가려는 사람들과 비교합니다. 많은 것들이 있습니다. 이런 일이 어떻게 작동하는지 봅시다.
여기서 우리는 먼저 우리의 전제 조건을 분명히합니다. 객체에는 하나 이상의 동기화 된 방법이 있습니다. 그렇지 않으면이 키의 요점은 무엇입니까? 물론, 우리에게는 그러한 주제가 없을 것입니다.
한 남자가 잠긴 방에 들어가고 싶었습니다. 그는 집의 문에 와서 열쇠를 보았습니다 (아직 잠긴 방을 사용하고 싶지 않다는 것을 의미합니다). 그래서 그는 걸어 가서 열쇠를 가져 와서 계획대로 방을 사용했습니다. 매번 잠긴 방을 사용한 직후에 키를 반환 할 것입니다. 그가 잠긴 객실 두 개를 연속으로 사용하고 싶더라도 키를 반환하여 검색합니다. 따라서 일반적인 경우에 키를 사용하는 원리는 다음과 같습니다. "사용하는대로 빌려 사용하자마자 반환하십시오."
현재 다른 사람들은 잠금 해제 된 객실을 제한없이 사용할 수 있습니다. 한 사람은 한 방을 사용할 수 있고 두 사람은 제한없이 한 방을 사용할 수 있습니다. 그러나 누군가가 잠긴 방에 들어가기를 원한다면, 그는 문으로 달려 가서 살펴 봐야합니다. 물론 열쇠가 있다면 떠날 것입니다. 가지고 있지 않으면 기다릴 수 있습니다. 많은 사람들 이이 키를 기다리고 있다면 누가 키를 반환 한 후에 누가 먼저 키를 얻을 수 있습니까? 보장되지 않습니다. 앞의 예를 들어, 잠긴 방을 연속으로 사용하고 싶었던 사람과 마찬가지로, 중간에 열쇠를 기다리는 다른 사람들이 있다면,이 사람이 다시 그것을 얻을 것이라는 보장은 없었습니다. (Java Specity는 Resid.sleep ()가 휴식 후에 실행되는 데 걸리는 데 걸리는 시간, 동일한 우선 순위를 가진 스레드가 먼저 실행되는 데 걸리는 시간과 같은 많은 장소에서 보장되지 않는다는 것을 명백히 명시하고 있으며, 대기 풀에있는 스레드가 객체에 액세스 할 수있는 잠금 장치가 릴리스 된 후에 우선 순위가 부여 될 것입니다. 최종 결정이 JVM에있는 이유가 아니라고 생각합니다. 조건이지만 많은 기사를 기반으로합니다.
판단 조건이 너무 많기 때문에 말하면 Java의 홍보에 영향을 줄 수 있거나 지적 재산 보호로 인한 것일 수 있습니다. Sun은 나에게 약속을 주었고 그것을 통과했습니다. 그것에 아무런 문제가 없습니다. 그러나 나는 이러한 불확실성이 완전히 불확실하지 않다고 생각합니다. 컴퓨터 자체가 지침에 따라 실행되기 때문입니다. 현상이 무작위로 보이더라도 실제로는 규칙적입니다. 컴퓨터를 연구 한 사람은 컴퓨터에서 임의의 숫자의 과학적 이름이 의사 랜덤 숫자이며 특정 방법을 사용하는 사람들이 작성하고 무작위로 보인다는 것을 알고 있습니다. 또한, 아마도 확실하지 않기 때문에 너무 의미가 없기 때문에 확실하지 않다면 확실하지 않습니다. ))
동기화 코드 블록을 살펴 보겠습니다. 동기화 방법과 약간의 차이가 있습니다.
1. 크기 측면에서 동기화 코드 블록은 동기화 방법보다 작습니다. 동기화 코드 블록을 잠금 화면으로 분리 된 잠금 해제 실의 공간으로 생각할 수 있습니다.
2. 동기화 코드 블록은 다른 객체를 얻는 키를 인위적으로 지정할 수 있습니다. 화면 잠금을 해제 할 키를 지정하는 것과 마찬가지로이 방의 키를 사용할 수 있습니다. 다른 집의 열쇠가 그것을 열 수 있음을 지정할 수도 있습니다. 이런 식으로, 당신은 그 열쇠를 가져오고 그 집의 열쇠를 사용 하여이 집의 잠긴 화면을 열어야합니다.
당신이 얻은 다른 집의 열쇠는 그 집에 자물쇠없이 방에 들어가는 다른 사람들에게 영향을 미치지 않는다는 것을 기억하십시오.
동기 코드 블록을 사용하는 이유는 무엇입니까? 우선, 프로그램의 동기화 부분은 작동 효율에 많은 영향을 미치며 방법은 일반적으로 일부 로컬 변수를 생성 한 다음 작업, 디스플레이 등과 같은 이러한 변수에 대해 일부 작업을 수행하는 것입니다. 동기화로 인해 코드가 많을수록 효율성에 대한 영향이 심각합니다. 따라서 우리는 보통 그 영향을 좁히려고 노력합니다.
어떻게해야합니까? 코드 블록 동기화. 작업과 같은 한 가지 방법으로 동기화 위치를 동기화합니다.
또한 키를 지정할 수있는 동기 코드 블록의 기능은 추가 이점이 있습니다. 즉, 특정 기간 내에 객체의 키를 차지할 수 있습니다. 앞에서 언급 한 일반적인 상황에서 키를 사용하는 원리를 기억하십니까? 지금은 평범한 상황이 아닙니다. 당신이 얻은 키는 반환되지 않았지만 동기 코드 블록을 종료 할 때만 반환됩니다.
나는 또한 두 개의 잠긴 방을 연속으로 사용하고 싶었던 사람을 사용하여 모범을 보였습니다. 사용 후 다른 것을 계속 사용할 수 있습니까? 동기 코드 블록을 사용하십시오. 먼저 다른 스레드를 만들고 동기 코드 블록을 만들고 해당 코드 블록의 잠금 장치를 집 열쇠로 가리 킵니다. 그런 다음 해당 스레드를 시작하십시오. 코드 블록에 들어갈 때 집으로 열쇠를 잡을 수있는 한 코드 블록을 종료 할 때까지 보관할 수 있습니다. 다시 말해,이 방에있는 모든 잠긴 방을 가로 질러 나도 잠을 자거나 (10*60*1000),이 키를 기다리는 1,000 개의 스레드가 여전히 있습니다. 매우 즐겁습니다.
여기서 우리는 수면 () 방법과 키 사이의 상관 관계에 대해 이야기 할 것입니다. 키를 얻은 후 스레드가 잠을 자고 동기 내용을 완료하지 않은 경우 키는 여전히 있습니다. 키는 다시 실행되고 모든 동기 컨텐츠를 완료 할 때까지 반환되지 않습니다. 그 사람은 일에 지쳤다는 것을 기억하십시오. 그래서 그는 휴식을 취하기 위해 갔고, 그가 할 일을 끝내지 않았습니다. 다른 사람들이 방에 들어가서 엉망이되는 것을 피하기 위해서는 자고있을 때도 몸에 유일한 열쇠를 입어야합니다.
마지막으로, 어떤 사람들은 왜 열쇠와 문 대신 열 키가 필요합니까? 나는 이것이 복잡성 때문이라고 생각합니다. 물론 하나의 열쇠와 하나의 문은 더 안전하지만 많은 문제가 필요합니다. 열쇠의 생성, 스토리지, 획득, 반품 등. 그것의 복잡성은 동기화 방법의 증가와 함께 기하학적 시퀀스의 증가가 될 수 있으며, 이는 효율성에 심각한 영향을 미칩니다. 이것은 또한 트레이드 오프입니다. 안전을 약간 높이고 효율성을 크게 줄이는 것이 바람직하지 않습니다.
동기화 된 간단한 예
public class textthread {public static void main (string [] args) {txtthread tt = new TxtThread (); 새 스레드 (tt) .start (); 새 스레드 (tt) .start (); 새 스레드 (tt) .start (); 새 스레드 (tt) .start (); }} class txtthread는 runnable {int num = 100; String str = new String (); public void run () {synchronized (str) {while (num> 0) {try {thread.sleep (1); } catch (예외 e) {e.getMessage (); } system.out.println (Thread.currentThread (). getName () + "이것은" + num--); }}}}위의 예에서, 시차를 만들기 위해, 즉 오류를 만들 수있는 기회, Thread.sleep (10)가 사용됩니다.
멀티 스레딩을위한 Java의 지원 및 동기화 메커니즘은 매우 인기가 있습니다. 동기화 된 키워드를 사용하면 멀티 스레드 공유 데이터 동기화 문제를 쉽게 해결할 수 있습니다. 정확히 뭐야? 또한 결론을 내리기 전에 동기화 된 키워드의 역할에 대한 심층적 인 이해가 필요합니다.
일반적으로 동기화 된 키워드는 함수의 수정 자 또는 함수 내의 문으로 사용할 수 있으며, 이는 일반적으로 언급되는 동기화 메소드 및 동기화 문 블록입니다. 보다 신중하게 분류하면 동기화 된 것은 인스턴스 변수, 객체 참조, 정적 함수 및 클래스 리터럴 (클래스 이름 리터럴 상수)에서 작용할 수 있습니다.
더 자세히 설명하기 전에 몇 가지 요점을 명확히해야합니다.
A. 동기화 된 키워드가 메소드 또는 객체에 추가 되든, 획득하는 잠금은 코드 나 기능을 잠금으로 처리하는 대신 객체이며 동기화 방법은 훨씬 더 가능성이 높습니다.
그의 실에 객체 액세스.
B. 각 객체에는 하나의 잠금 장치 만 있습니다.
C. 동기화를 구현하려면 비용으로 많은 시스템 간접비가 필요하며 교착 상태를 유발할 수도 있으므로 불필요한 동기화 제어를 피하십시오.
다음으로 코드에서 다른 장소를 사용하여 동기화의 영향에 대해 논의 해 봅시다.
P1과 P2가 동일한 클래스의 다른 객체라고 가정하면,이 클래스는 다음 상황에서 동기화 블록 또는 동기화 방법을 정의하고 P1과 P2를 호출 할 수 있습니다.
1. 동기화 된 기능 수정 자로 사용되면 예제 코드는 다음과 같습니다.
public synchronized void methodaaa () {//….}이것은 동기화 방법입니다. 그렇다면 현재 어떤 객체가 동기화되어 있습니까? 잠금은이 동기 메소드 객체를 호출하는 것입니다. 즉, 객체 P1이 다른 스레드 에서이 동기화 메소드를 실행할 때 동기화의 효과를 달성하기 위해 상호 배제가 형성됩니다. 그러나이 객체가 속한 클래스별로 생성 된 다른 객체 P2는 동기화 된 키워드가 추가 된 상태 에서이 메소드를 임의로 호출 할 수 있습니다.
위의 예제 코드는 다음 코드와 같습니다.
public void methodaaa () {synchronized (this) // (1) {//… ..}}(1) 요점에서 이것은 무엇을 의미합니까? P1과 같은이 방법을 호출하는 객체를 나타냅니다. 동기화 방법은 본질적으로 객체 참조에 동기화 된 적용을 알 수 있습니다. P1 객체 잠금을 얻은 스레드 만 P1 동기화 방법을 호출 할 수 있습니다. P2의 경우 P1 잠금 장치와 관련이 없습니다. 이 프로그램은이 상황에서 동기화 메커니즘의 제어를 제거하여 데이터 혼란을 일으킬 수 있습니다.
2. 블록 동기화, 샘플 코드는 다음과 같습니다.
public void method3 (someObject so) {synchronized (so) {//… ..}}현재 잠금 장치는 SO의 대상입니다. 잠금을받는 사람은 제어하는 코드를 실행할 수 있습니다. 잠금 장치로 명확한 객체가 있으면 이와 같은 프로그램을 작성할 수 있지만 잠금 장치로 명확한 객체가없고 동기화 할 코드 조각을 원할 때 특수 인스턴스 변수 (객체가되어야 함)를 만들 수 있습니다.
클래스 foo는 런닝 가능한 {private byte [] lock = new Byte [0]를 구현합니다. // 특수 인스턴스 변수 public void methoda () {synchronized (lock) {//…}} //… ..}참고 : 제로 길이의 바이트 배열 객체는 컴파일 된 바이트 코드를 작성하는 데 어떤 객체보다 경제적입니다. 0 길이 바이트 [] 객체를 생성하려면 3 개의 opcode 만 있으면됩니다.
3. 정적 함수에 동기화 된 사용 예제 코드는 다음과 같습니다.
클래스 foo {public synchronized static void methodaaa () // 동기화 된 정적 함수 {//…. } public void methodbbb () {synchronized (foo.class) // 클래스 리터럴 (클래스 이름 문자 상수)}}코드의 MethodBBB () 메소드는 클래스 리터럴을 잠금으로 사용합니다. 동기화 된 정적 함수와 동일한 효과가 있습니다. 얻은 자물쇠는 매우 특별합니다. 현재이 메소드라고하는 객체가 속한 클래스 (클래스,이 클래스에서 생성 된 특정 객체가 아님)입니다.
"Effection Java"책에서 Foo.class 및 P1.getClass ()를 동기 잠금 장치로 사용하는 것을 보았고 P1.getClass ()는이 클래스를 잠그는 목적을 달성하는 데 사용할 수 없다는 것을 기억합니다. P1은 FOO 클래스에서 생성 된 객체를 나타냅니다.
클래스가 동기화 된 정적 함수 A와 동기화 된 인스턴스 기능 B를 정의하면이 클래스의 동일한 객체 OBJ가 잠금이 다르기 때문에 여러 스레드에서 A와 B에 액세스 할 때 동기화되지 않습니다. 방법 A의 잠금은 객체 OBJ이고 B의 잠금은 OBJ가 속하는 클래스입니다.
요약은 다음과 같습니다.
어떤 객체 동기화 된 잠금을 찾으면 더 안전한 멀티 스레드 프로그램을 설계하는 데 도움이 될 수 있습니다. 공유 리소스에 대한 동기식 액세스를보다 안전하게 만드는 몇 가지 팁이 있습니다.
1. PRIVATE +의 인스턴스 변수를 정의하십시오. 공개/보호 된 인스턴스 변수 대신 get 메소드를 정의하십시오. 변수가 공개로 정의되면 객체는 동기화 방법의 제어를 우회하여 직접 얻고 변경할 수 있습니다. 이것은 또한 Javabean의 표준 구현 방법 중 하나입니다.
2. 인스턴스 변수가 배열 또는 배열리스트와 같은 객체 인 경우, 외부 객체가 GET 메소드를 통해 인스턴스 객체에 대한 참조를 가져 와서 다른 객체를 가리키면 개인 변수가 변경되므로 위의 메소드는 여전히 안전하지 않습니다. 현재 get 메소드에 동기화 된 추가를 추가 하고이 개인 객체의 클론 () 만 반환하여 발신자가 객체 사본에 대한 참조를 가져옵니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.