소개
Java는 JDK1.5 이후 java.util.concurrent.atomic 패키지를 제공하며, 이는 프로그래머가 다중 스레드 환경에서 잠금없이 원자 작업을 수행하도록 촉진합니다. 원자 변수의 기본 층은 프로세서가 제공하는 원자 지침을 사용하지만 다른 CPU 아키텍처는 다른 원자 지침을 제공 할 수 있으며 어떤 형태의 내부 잠금이 필요할 수도 있으므로이 방법은 스레드가 차단되지 않도록 절대적으로 보장 할 수 없습니다.
원자 패키지 소개
원자 패키지에는 12 개의 클래스가 있으며 4 가지 원자 업데이트 방법은 원자 업데이트 기본 유형, 원자 업데이트 배열, 원자 업데이트 참조 및 원자 업데이트 필드입니다. 원자 패키지의 클래스는 기본적으로 안전하지 않은 것을 사용하여 구현 된 클래스입니다.
원자 업데이트 기본 유형 클래스
원자 메소드를 통해 기본 유형을 업데이트하기 위해 원자 패키지는 다음 세 가지 클래스를 제공합니다.
AtomicBoolean : Atomic은 부울 유형을 업데이트합니다.
Atomicinteger : 원자 업데이트 정수.
Atomiclong : 원자 업데이트 긴 정수.
Atomicinteger의 일반적인 방법은 다음과 같습니다.
int addandget (int delta) : 인스턴스의 값 (atomicinteger의 값)에 입력 값을 원자 방식으로 추가하고 결과를 반환합니다.
Boolean CompareAndset (int expect, int update) : 입력 값이 예상 값과 같으면 값을 원자로 입력 값으로 설정하십시오.
int getAndIncrement () : 현재 값을 1에 1에 추가합니다. 참고 : 여기서 반환 된 값은 자동화 전의 값입니다.
Void Lazyset (int newValue) : 결국 NewValue로 설정됩니다. Lazyset을 사용하여 값을 설정 한 후에도 다른 스레드는 여전히 이전 값 int getAndset (int newValue)을 읽을 수 있습니다. 이는 원자 방식으로 NewValue의 값으로 설정되어 이전 값을 반환합니다.
Atomicinteger 예제 코드는 다음과 같습니다.
import java.util.concurrent.atomic.atomicinteger; public class atomicintegertest {static atomicinteger ai = new atomicinteger (1); public static void main (string [] args) {system.out.println (ai.getAndincrement ()); system.out.println.println (ai.get ()).산출
12
저녁 식사 후 디저트
원자 패키지는 세 가지 기본 유형의 원자 업데이트를 제공하지만 Java 기본 유형에는 Char, Float 및 Double이 포함됩니다. 문제는 다른 기본 유형의 원자를 업데이트하는 방법입니다. 원자 패키지의 클래스는 기본적으로 안전하지 않은 것을 사용하여 구현됩니다. 안전하지 않은 소스 코드를 살펴 보겠습니다. 안전하지 않은 것은 3 가지 CAS 방법, 즉 비교 대상, 비교와 핀드 스웨이 플롱을 제공한다는 것을 발견했습니다. 그런 다음 AtomicBoolean 소스 코드를보십시오. 우리는 먼저 부울을 정수로 변환 한 다음 CAS에 비교와 핀을 사용하므로 비슷한 아이디어를 사용하여 Atomic Update Double도 구현할 수 있습니다.
원자 업데이트 배열 클래스
원자 패키지는 다음 세 가지 클래스를 제공합니다.
atomicintegerarray : 원자 적으로 정수 배열에서 요소를 업데이트합니다.
Atomiclongarray : Atomic은 긴 배열로 요소를 업데이트합니다.
AtomicreferenceArray : Atomic 업데이트는 참조 유형 배열의 요소를 업데이트합니다.
AtomicinteGerArray 클래스는 주로 배열의 정수를 업데이트 할 수있는 원자력을 제공합니다. 일반적으로 사용되는 방법은 다음과 같습니다
int addandget (int i, int delta) : 배열의 요소 인덱스 I에 원자 값을 원자 적으로 추가합니다.
Boolean CompareAndset (int i, int expect, int update) : 현재 값이 예상 값과 같으면 배열 위치의 요소는 업데이트 값으로 원자가로 설정됩니다.
예제 코드는 다음과 같습니다.
public class atomicintegerarraytest {static int [] value = new int [] {1, 2}; static atomicintegerarray ai = new atomicintegerarray (value); public static void main (string [] args) {ai.getandset (0, 3); system.out.println (ai.get (0)); System.out.println (value [0]);}}산출
31
AtomicintegerArray 클래스에서 주목해야 할 것은 배열 값이 생성자 메소드를 통해 전달 된 다음 AtomicinTegerArray가 현재 배열을 복사하므로 AtomicinTegerArray가 내부 배열 요소를 수정하면 전달 된 어레이에 영향을 미치지 않습니다.
원자 업데이트 참조 유형
기본 유형 인 Atomicinteger는 하나의 변수 만 업데이트 할 수 있습니다. 여러 변수를 원자 적으로 업데이트하려면이 원자를 사용하여 참조 유형으로 제공된 클래스를 업데이트해야합니다. 원자 패키지는 다음 세 가지 클래스를 제공합니다.
Atomicreference : Atomic은 참조 유형을 업데이트합니다.
AtomicreferenceFieldUpdater : 원자력 업데이트 참조 유형의 필드.
AtomicmarkableReference : Atomic은 마커 비트로 참조 유형을 업데이트합니다. 부울 타입 태그 비트 및 참조 유형을 원자 적으로 업데이트 할 수 있습니다. 시공 방법은 AtomicmarkableReference (V InitialRef, Boolean InitialMark)입니다.
Atomicreference 사용 코드는 다음과 같습니다.
public class atomicreferencetest {public static atomicreference <user> atomicuserref = new atomicreference </user> <user> (); public static void main (String [] args) {user user = new user ( "conan", atomicuserref.set (user) = new User ( "Shinichi", "Shinichi", "Shinichi", "Shinichi" 17; old;} public String getName () {return name;} public int getold () {return old;}}}산출
Shinichi17
원자 업데이트 필드 클래스
특정 클래스에서 특정 필드 만 있으면 Atomic을 사용하여 필드 클래스를 업데이트해야합니다. 원자 패키지는 다음 세 가지 클래스를 제공합니다.
AtomicintegerfieldUpdater : 정수를 원자력으로 업데이트하는 필드의 업데이트.
Atomiclongfieldupdater : 원자 업데이트를위한 업데이트는 긴 정수 필드입니다.
AtomicStampedReference : Atomic은 버전 번호로 참조 유형을 업데이트합니다. 이 클래스는 정수 값을 참조와 연관시키고 원자가 더 많은 데이터 및 버전 번호에 사용할 수 있으며, 이는 원자 업데이트에 CAS를 사용할 때 발생할 수있는 ABA 문제를 해결할 수 있습니다.
원자 업데이트 필드 클래스는 추상 클래스이며, 사용할 때마다 정적 메소드 NewUpdater를 사용하여 업데이트를 만들어야합니다. 대중 휘발성 수정자는 원자 업데이트 클래스의 필드에 사용해야합니다.
첫 번째 단계는 원자 업데이트 필드 클래스가 추상 클래스이기 때문에 정적 메소드 atomicintegerfieldupdater.newupdater를 사용할 때마다 업데이트를 만들어야하며 업데이트하려는 클래스와 속성을 설정해야한다는 것입니다. 두 번째 단계는 클래스의 필드 (속성)를 업데이트하는 것입니다.
Atomicintegerfieldupdater의 예제 코드는 다음과 같습니다.
공개 클래스 atomicintegerfieldupdatertest {private static atomicintegerfieldupdater <user> a = atomicintegerfieldupdater.newupdater (user.class, "old"); public static void main (String [] args) {user conan = new user ( "conan", 10); system.out.println (a.getandincrement (conan)); system.out.println (a.get (conan));} public static class user {private String name; public volatile int old; public user (문자열 이름, int old) {this.name = name; this.old = old;} {return getname ()}}}}}}}}산출
1011
요약
위는 Java Multi-Shreaded Atomic 패키지의 소개 및 사용에 관한이 기사의 전체 내용입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구들은이 사이트를 계속 참조 할 수 있습니다.
Java Multithreading의 다양한 조건에서 생산 소비자 모델 작성 방법 소개
Java Multithreaded 프로그래밍 동기화기 향후 및 FutureTask 구문 분석 및 코드 예제
Java 멀티 스레드 디스플레이 잠금 및 내장 잠금에 대한 자세한 설명
단점이 있으면 메시지를 남겨 두십시오.