java 다중 루틴 프로그래밍 사용 Synchronized 블록 동기화 변수
package mythread;
public class SyncThread extends Thread
{
private static String sync = "";
private String methodType = "";
private static void method(String s)
{
synchronized (sync)
{
sync = s;
System.out.println(s);
while (true);
}
}
public void method1()
{
method("method1");
}
public static void staticMethod1()
{
method("staticMethod1");
}
public void run()
{
if (methodType.equals("static"))
staticMethod1();
else if (methodType.equals("nonstatic"))
method1();
}
public SyncThread(String methodType)
{
this.methodType = methodType;
}
public static void main(String[] args) throws Exception
{
SyncThread sample1 = new SyncThread("nonstatic");
SyncThread sample2 = new SyncThread("static");
sample1.start();
sample2.start();
}
}
실행 결과는 다음과 같습니다
method1
staticMethod1
위의 운행 결과를 보고 많은 독자들이 놀랐을 것이다.위의 코드에서method1과staticMethod1 방법은 정적 문자열 변수sync를 사용하여 동기화합니다.이 두 가지 방법은 하나만 동시에 실행할 수 있고, 이 두 가지 방법은 모두 014줄의 무한순환 문장을 실행할 수 있다.따라서 출력 결과는 method1과staticMethod1 중 하나일 수밖에 없습니다.그러나 이 프로그램은 이 두 문자열을 모두 출력했다.이런 결과가 나오기를 바라는 것은 매우 간단하다. 우리는 012행을 보면 알 수 있다.이 줄에서sync의 값을 바꿨습니다.여기서 Java의 String 유형을 설명합니다.String 유형은 Java의 다른 복잡한 유형과 다릅니다.String 변수를 사용할 때 이 변수에 값을 한 번만 부여하면 Java는 새로운 String 유형의 실례를 생성합니다.다음 코드와 같습니다.
String s = "hello";
System.out.println(s.hashCode());
s = "world";
System.out.println(s.hashCode());
위의 코드에서첫 번째 s와 다시 값을 부여한 s의hashCode의 값은 다르다.String 클래스를 만드는 실례는 new를 사용할 필요가 없기 때문에, String 형식의 변수를 동기화할 때 이 변수에 값을 부여하지 마십시오. 그렇지 않으면 변수를 동기화할 수 없습니다.012행에서sync를 위한 새로운 실례를 만들었기 때문에method1이 먼저 실행된다고 가정하면,method1 방법이 013행의 코드를 실행한 후,sync의 값은 최초의 값이 아니며,method1 방법이 잠긴 것은 여전히sync 변수의 최초의 값입니다.이때 static Method1은synchronized(sync)에 마침 실행되었다. static Method1 방법에서 잠그려는 이sync와method1 방법으로 잠그는sync는 이미 하나가 아니기 때문에 이 두 방법의 동기성은 이미 파괴되었다.위와 같은 문제를 해결하는 방법은 당연히 012행을 없애는 것이다.이 예에 이 줄을 추가하면 클래스 변수를 사용하여 동기화 방법을 설명할 때synchronized 블록에서 동기화 변수의 값을 바꾸면 방법 간의 동기화를 파괴할 수 있습니다.이러한 상황을 철저히 피하기 위해 동기화 변수를 정의할 때final 키워드를 사용할 수 있습니다.위의 프로그램에서 005 행을 다음과 같이 변경할 수 있습니다.
private final static String sync = "";
final 키워드를 사용하면sync는 정의할 때만 값을 부여할 수 있고 나중에 수정할 수 없습니다.만약 프로그램의 다른 곳에서sync에 값을 부여한다면, 프로그램은 컴파일할 수 없습니다.Eclipse 등 개발 도구에서는 잘못된 곳에 직접 힌트를 줍니다.우리는 두 가지 측면에서synchronized 블록을 이해할 수 있다.만약 유형 방법의 측면에서 이해한다면 유형 변수를 통해 상응하는 방법을 동기화할 수 있다.클래스 변수의 측면에서 이해하면synchronized 블록을 사용하여 특정한 클래스 변수가 한 방법으로만 접근할 수 있도록 보장할 수 있습니다.어느 각도에서 이해하든지 그들의 실질은 똑같다. 바로 유형 변수를 이용하여 동기화 자물쇠를 얻고 동기화 자물쇠의 상호 배척성을 통해 동기화를 실현하는 것이다.주의:synchronized 블록을 사용할 때synchronized 블록은 대상을 매개 변수로만 사용할 수 있음을 주의해야 합니다.간단한 형식의 변수 (예를 들어 int,char,boolean 등) 라면synchronized를 사용하여 동기화할 수 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약 동료는 무심결에 이 문제를 제기하고 두 가지 방법을 직접 실천했다.물론 더 좋은 방법이 있을 거야. 방법 1 이런 방법은 비교적 흔히 볼 수 있는 해결 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.