게임 자바 강의 - 자바 스 레 드 동기 화 (1)
동시 프로 그래 밍 에서 여러 개의 실행 스 레 드 가 자원 을 공유 하 는 문제 에 자주 부 딪 힐 수 있다.예 를 들 어 여러 스 레 드 가 동시에 파일 을 읽 고 쓰기, 공용 데이터베이스 연결, 전역 카운터 등 이다.많은 스 레 드 간 의 동기 화 문 제 를 처리 하지 않 으 면 상태 가 일치 하지 않 거나 다른 오 류 를 일 으 키 기 쉽다.
동기 화 는 하나의 스 레 드 가 대상 이 일치 하지 않 는 상 태 를 보 는 것 을 막 을 수 있 을 뿐만 아니 라 동기 화 방법 이나 블록 에 들 어 가 는 모든 스 레 드 를 확보 할 수 있 으 며 같은 자물쇠 로 보호 되 기 전의 모든 수정 결 과 를 볼 수 있다.동기 화 를 처리 하 는 관건 은 임계 조건 (critical section), 즉 다 중 스 레 드 접근 / 공유 자원 의 코드 블록 을 정확하게 식별 하 는 것 이다.
키워드 synchronized 는 같은 시간 을 보장 할 수 있 습 니 다. 하나의 스 레 드 만 이 특정한 방법 이나 코드 블록 을 실행 할 수 있 습 니 다.또한 자바 언어 규범 은 하나의 변 수 를 읽 고 쓰 는 것 이 원자 임 을 보증 합 니 다. log 나 double 을 제외 하고 언어 규범 은 스 레 드 가 원자 데 이 터 를 읽 을 때 임의의 수 치 를 보지 못 하도록 보장 하지만 한 스 레 드 가 기록 한 값 이 다른 스 레 드 에 대해 볼 수 있 고 스 레 드 간 의 통신, 동기 화 는 필요 합 니 다.
synchronized 동기 화 방법:
우 리 는 synchronized 키 워드 를 방법 앞 에 두 고 하나의 스 레 드 만 이 방법 을 실행 할 수 있 도록 보장 할 수 있 습 니 다.주의해 야 할 것 은 하나의 정적 방법 과 인 스 턴 스 방법 이 synchronized 가 있다 면 한 스 레 드 가 정적 방법 에 접근 하고 다른 스 레 드 가 인 스 턴 스 방법 에 접근 하 는 것 을 허용 하 는 것 입 니 다.예 를 들 면:
private static synchronized void stopRequested(){
stopRequest = true;
}
synchronized 방법 은 아주 짧 은 수정 이나 공유 자원 을 읽 는 것 일 뿐 이 며, 그렇지 않 으 면 성능 문 제 를 일 으 킬 수 있 습 니 다. synchronized 는 본질 적 으로 서로 배척 하기 때 문 입 니 다.
synchronized 동기 블록:
synchronized (this) {
// Java code
}
동기 블록 은 임계 구간 만 동기 화하 고 나머지 부분 은 병행 할 수 있 습 니 다.서로 독립 된 공유 자원 에 대해 서 는 서로 다른 자물쇠 로 동기 화 할 수 있다.예 를 들 어 두 개의 영화관 표를 동시에 판매한다.
public class Cinema {
private long vacanciesCinema1;
private long vacanciesCinema2;
private final Object controlCinema1, controlCinema2;
public Cinema() {
controlCinema1 = new Object();
controlCinema2 = new Object();
vacanciesCinema1 = 20;
vacanciesCinema2 = 20;
}
public boolean sellTickets1(int number) {
synchronized (controlCinema1) {
if (number < vacanciesCinema1) {
vacanciesCinema1 -= number;
return true;
} else {
return false;
}
}
}
public boolean sellTickets2(int number) {
synchronized (controlCinema2) {
if (number < vacanciesCinema2) {
vacanciesCinema2 -= number;
return true;
} else {
return false;
}
}
}
}
읽 기와 쓰기 primitive 형식 은 원자 이지 만 스 레 드 간 에 동기 화 되 지 않 으 면 데이터 불일치 문 제 를 일 으 킬 수 있 습 니 다. 다음 예 를 보 세 요.
public class TestStop {
private static boolean stopRequest;
public static void main(String[]args) throws InterruptedException{
Thread t = new Thread( new Runnable(){
public void run(){
int i = 0;
while(!stopRequest){
i++;
}
}
});
t.start();
TimeUnit.SECONDS.sleep(2);
stopRequest = true;
}
}
이 코드 는 때때로 멈 출 수 없습니다. 왜냐하면 하위 스 레 드 가 stopRequest 에 대한 변경 사항 을 보지 못 했 기 때 문 입 니 다.해결 방법 은 공유 변수 에 대한 동기 화 접근 을 추가 하 는 것 입 니 다.
public class TestStop {
private static boolean stopRequest;
private static synchronized void stopRequested(){
stopRequest = true;
}
private static synchronized boolean getStopRequest(){
return stopRequest;
}
public static void main(String[]args) throws InterruptedException{
Thread t = new Thread( new Runnable(){
public void run(){
int i = 0;
while(!getStopRequest()){
i++;
}
}
});
t.start();
TimeUnit.SECONDS.sleep(2);
stopRequested();
}
}
읽 기와 쓰기 가 동기 화 되 지 않 으 면 동기 화 는 효과 가 없다.이 경우 volatile 로 동기 화 를 없 앨 수 있다.
후속 장 에서 저 희 는 synchronize 와 Lock 에 관 한 내용 을 더 소개 할 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.