java 다중 루틴 프로그래밍의 신중한volatile 키워드 사용

volatile 키워드는 자바 다중 스레드를 이해하는 독자들이 그 역할을 잘 알고 있다고 믿는다.volatile 키워드는 int,float,boolean 등 데이터 형식을 설명하는 데 사용됩니다.만약 이러한 간단한 데이터 형식이volatile라고 성명된다면, 그것들에 대한 조작은 원자 수준이 될 것이다.하지만 일정한 제한이 있다.예를 들어 아래의 예에서 n은 원자급이 아니다

package mythread;

public class JoinThread extends Thread
{
public static volatile int n = 0;
public void run()
{
for (int i = 0; i < 10; i++)
try
{
n = n + 1;
sleep(3); // , 3

}
catch (Exception e)
{
}
}

public static void main(String[] args) throws Exception
{

Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 100
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
// 100
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}

만약에 n에 대한 조작이 원자급이라면 마지막 출력의 결과는 n=1000이어야 하고 면적 코드를 실행할 때 많은 경우 n이 1000보다 작다는 것은 n=n+1이 원자급의 조작이 아니라는 것을 설명한다.왜냐하면volatile로 성명된 간단한 변수가 현재 값이 이 변수의 이전 값과 관련이 있다면volatile 키워드는 작용하지 않는다. 즉, 다음과 같은 표현식은 원자 조작이 아니다

n = n + 1;
n++;
이러한 상황을 원자 조작으로 만들려면synchronized 키워드를 사용해야 합니다. 위의 코드는 다음과 같은 형식으로 바꿀 수 있습니다

package mythread;

public class JoinThread extends Thread
{
public static int n = 0;

public static synchronized void inc()
{
n++;
}
public void run()
{
for (int i = 0; i < 10; i++)
try
{
inc(); // n = n + 1 inc();
sleep(3); // , 3

}
catch (Exception e)
{
}
}

public static void main(String[] args) throws Exception
{

Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 100
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
// 100
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}

위의 코드는 n=n+1을 inc()로 바꿨습니다. 그 중에서 inc 방법은synchronized 키워드를 사용하여 동기화합니다.따라서volatile 키워드를 사용할 때 신중해야 한다. 간단한 유형의 변수가volatile 수식만 사용하는 것이 아니라 이 변수에 대한 모든 조작은 원래 조작이다. 변수의 값이 자신의 이전 결정에 의해 결정될 때, 예를 들어 n=n+1, n++ 등,volatile 키워드는 효력을 잃는다. 변수의 값이 자신의 이전 값과 무관할 때만 이 변수에 대한 조작이 원자 등급이다. 예를 들어 n=m+1, 이것이 바로 원래 등급이다.그러므로volatile를 사용할 때 반드시 조심해야 한다. 만약 자신이 자신이 자신이 없다면synchronized를 사용하여volatile를 대체할 수 있다.

좋은 웹페이지 즐겨찾기