> Java > java지도 시간 > 본문

다중 스레드 동시성에 대한 몇 가지 문제 공유

零下一度
풀어 주다: 2017-06-28 09:13:08
원래의
1496명이 탐색했습니다.

1 개요

1.휘발성

은 공유 데이터가 수정되면 즉시 공유 메모리(힙 또는 메소드 영역)에 동기화되도록 보장합니다.

2. 스레드가 힙의 데이터에 액세스하는 과정

스레드는 스택에 변수의 복사본을 생성하고 수정 후 데이터를 힙에 동기화합니다.

3. 명령어 재배열

실행 효율성을 높이기 위해 CPU는 종속성이 없는 명령어를 재정렬합니다. 재정렬을 제어하려면 휘발성을 사용하여 변수를 수정할 수 있습니다. 변수가 포함된 명령어 앞과 뒤의 명령어는 독립적으로 정렬되며, 앞과 뒤의 명령어는 교차 정렬될 수 없습니다.

두 가지 일반적인 문제 및 해결 방법

1. 원자성 문제

소위 원자성이란 작업이 중단될 수 없다는 것을 의미합니다. 즉, 다중 스레드 동시 환경에서는 작업이 시작되면, 실행은 동일한 CPU 시간 조각 내에 완료됩니다. 동일한 스레드의 여러 작업이 서로 다른 CPU 시간 조각에서 실행되는 경우 중간의 정체로 인해 일부 공유 데이터가 후속 작업 중에 다른 스레드에 의해 수정될 수 있으며 수정 내용이 현재 스레드에 동기화되지 않아 데이터가 발생합니다. 현재 스레드가 실제 데이터와 일치하지 않게 작동하는 이러한 일관성 없는 실행으로 인해 발생하는 데이터 불일치 문제를 원자성 문제라고 합니다. 2. 가시성 문제

가시성 문제는 스레드가 공유 데이터에 액세스하는 방식과 관련하여 발생합니다. 스레드가 힙(메서드 영역)의 변수에 액세스하면 먼저 스택에 변수의

복사본을 만든 다음 수정 후 이를 힙에 동기화합니다. 한 스레드가 방금 복사본을 생성한 후 다른 스레드가 변수를 수정하고 아직 힙에 동기화하지 않은 경우

이때 두 스레드가 동일한 변수를 동일한 상태에서 작동하는 현상이 발생합니다. i=9, 변수 i이므로 초기값은 9이고, 각 스레드의 연산은 마이너스

1입니다. 두 스레드 A와 B는 동시에 변수에 액세스하며, 결과 i=8을 힙에 동기화하기 전에 스레드 A도 i-1을 실행합니다. . 시간, 스레드 안전 문제가 발생했습니다. 스레드 안전 문제의 이유: 한 스레드의 공유 데이터 수정은 다른 스레드에서 즉시 볼 수 없습니다. 휘발성은 다음과 같은 솔루션을 제공합니다.
스레드가 휘발성으로 수정된 공유 데이터를 수정하면 이 수정 사항이 즉시 힙에 동기화되므로 다른 데이터가 힙의 공유 데이터에 액세스할 수 있습니다. 항상 최신 정보를 얻으세요. 여러 스레드에 걸친 값.

휘발성의 결함:
휘발성은 스레드가 힙에서 데이터를 얻을 때 스레드 가 힙에서 데이터를 복사한 경우에만 최신 값을 얻음을 보장할 수 있습니다. 작업이 완료되기 전에는 다른 스레드가 데이터를 수정했으며 수정된 데이터는 현재 스레드에 동기화되지 않습니다.

3. 순서 문제

실행 효율성을 높이기 위해 CPU는 종속성이 없는 명령을 재정렬합니다. 재정렬된 실행 결과는 순차 실행 결과와 동일합니다.

예를 들어, 소스 코드에서:

int i=0;

int y=1;
CPU는 실행 중에 먼저 "int y=1;"을 실행한 다음 "int i= 0;"인 경우 실행 결과는 순차적 실행 결과와 동일합니다.
단일 스레드 환경에서는 명령어 재정렬이 안전하지만 멀티 스레드 환경에서는 문제가 발생할 수 있습니다. 예:
스레드 A:

s=new String("sssss");//指令1flag=false;//指令2
로그인 후 복사

스레드 B:
while(flag){
doSome();
}
s.toUpperCase();//指令3
로그인 후 복사

스레드 A가 순차적으로 실행되는 경우, 즉 명령어 1을 실행한 다음 명령어 2를 실행하면 스레드 B의 실행에 문제가 없습니다. 명령어가 재배열된 후 스레드 A가 명령어 2를 먼저 실행하면
이는 플래그=true이고 스레드 2로 전환하여 루프를 종료하고 명령어 3을 실행합니다. s 객체가 아직 생성되지 않았으므로 널 포인터 예외가 발생합니다.
순서 문제의 원인:

A 스레드에는 공유 데이터에 대한 다른 스레드의 수정 작업에 대한 시퀀스 요구 사항이 있습니다. 예를 들어 스레드 B에서는 스레드 A가 명령어 1을 먼저 실행하고 명령어 2를 실행해야 합니다. 명령으로 인해 재배열이 실제로 필요한 순서대로 실행되지 않습니다. 이때 스레드 안전성 문제가 발생합니다.

해결 방법:

  1. 한 스레드만 동시에 공유 데이터에 액세스할 수 있도록 동기화 메커니즘을 사용하므로 이는 비효율적입니다.

  2. 휘발성을 사용하면 명령어에 휘발성으로 수정된 변수가 포함되어 있으므로 이 명령어의 실행 순서는 변경되지 않고 유지됩니다. 이 명령어 앞과 뒤의 명령어는 독립적으로 재배열될 수 있으며 교차 재배열될 수 없습니다.

참조:

위 내용은 다중 스레드 동시성에 대한 몇 가지 문제 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿