병렬 프로그래밍 회고: 원자 조작

원래 다중 루틴을 병발하여 프로그래밍한 학습 노트와 코드를 정리해서 붙여주세요.
---------------------------------
원자 조작
원자 조작
원자 조작은 라인 스케줄링 메커니즘에 의해 중단될 수 없는 조작이다.작업이 시작되면, 가능한 상하문 전환 전에 (다른 라인으로 전환) 실행할 수 있습니다.
원자 조작은 롱과 더블을 제외한 모든 기본 유형 위의 간단한 조작에 응용할 수 있다.롱과 더블 이외의 기본 형식 변수를 읽고 쓰기 위한 작업은 메모리를 분리할 수 없는 작업으로 간주될 수 있습니다.그러나 64비트의 롱과 더블 읽기와 쓰기는 2개의 분리된 32비트 작업으로 실행되며 읽기와 쓰기 작업 사이에 상하문 전환이 발생하여 서로 다른 작업이 부정확한 결과를 보게 된다.
롱과 더블을 정의할 때volatile을 사용하면 원자성을 얻을 수 있습니다.volatile로 표시된 영역은 메모리에 바로 기록되며, 읽기 동작은 메모리에서 발생합니다.
여러 개의 루트가 한 필드에 동시에 접근하면 이 필드는volatile이어야 합니다. 그렇지 않으면 이 필드는 동기화로만 접근할 수 있습니다.
그러나 한 필드의 값이 이전 값 (예를 들어 계수기) 에 의존하거나, 한 필드의 값이 다른 필드의 값 제한에 의존하면volatile가 정상적으로 작동하지 않습니다.그래서 첫 번째 선택은synchronized 키워드를 사용합니다.
2. 자바.util.concurrent.atomic
javase5부터 java가 새로 추가되었습니다.util.concurrent.atomic 패키지, JDK 문서에서 설명한 내용은 다음과 같습니다.
단일 변수에서 잠금을 해제하는 라인 보안 프로그래밍을 지원하는 작은 도구 패키지입니다.사실상 이 패키지의 클래스는volatile 값, 필드, 그룹 요소의 개념을 원자 조건 업데이트 작업을 제공하는 클래스로 확장할 수 있습니다.
아토믹 패키지에는 AtomicBoolean, AtomicInteger, AtomicLong, AtomicReference 등 원자성 변수 클래스가 제공됩니다.
원자성 변수 클래스를 사용하면 동기화 코드를 제거할 수 있지만 원자성 변수 클래스는java를 설계하는 데 사용된다.util.concurrent의 클래스이기 때문에 특수한 상황에서만 다시 사용합니다. 일반적으로 성능 개선에 사용됩니다.
다음은 AtomicInteger에 대한 간단한 테스트입니다.
public class AtomicIntegerTest implements Runnable{
	private AtomicInteger ait = new AtomicInteger(0);
	
	private void increment(){
		ait.addAndGet(2);
	}
	private int get(){
		return ait.get();
	}
	@Override
	public void run() {
		while(true){
			//         
			increment();
			try{
				TimeUnit.MILLISECONDS.sleep(200);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws Exception {
		ExecutorService es = Executors.newCachedThreadPool();
		AtomicIntegerTest task = new AtomicIntegerTest();
		for(int i=0;i<5;i++){
			es.submit(task);
		}
		TimeUnit.SECONDS.sleep(1);//  5        
		while(true){
			int value = task.get();
			if(value%2 != 0){
				System.out.println("error value!");
				System.exit(0);
			}else{
				System.out.println("value:"+task.get());
			}
			TimeUnit.MILLISECONDS.sleep(500);
		}
	}
}

위의 예시 프로그램에서 먼저 하나의 스레드 탱크를 만들고 5개의 스레드를 열었다. 모든 스레드는 원자성 변수 AtomicInteger에 2를 누적하고 AtomicInteger의 값을 반복해서 읽는다. 만약에 이 값이%2!=0이면 비원자적인 작업이 발생하고 프로그램이 멈추지만 이 프로그램은value의 값을 출력하기 위해 계속 실행됩니다.동시에 increment 방법이 잠기지 않았음을 주의하십시오.

좋은 웹페이지 즐겨찾기