자바 멀티스레드 공유변수 문제가 있습니다.


제가 자바로 컨솔게임을 만들면서 적군의 행동을 멀티스레드로 쓰고 있습니다.

스레드를 클래스로 따로 만들어 메인에서 start()시켜줍니다.

스레드안의 구조는 적군의 체력(static변수)이 0이하로 될 때까지 돌도록 반복문으로 돌렸고요.

하지만 멀티스레드이다보니까 적군의 체력이 0이하로 되어도 계속 돌더라고요.

우선 스레드 앞뒤로 출력값을 보아 제대로 적군의 체력이 0이하가 되는 지 확인을 했고, 이 점은 이상이 없었습니다.

그리고 싱글스레드로만 돌렸을 때는 동작이 멈추는 것을 확인했습니다.

그래서 찾아보니 스레드를 공유하여 접근한다면 run()메서드에 싱크로나이즈를 붙여주라고 해서

붙여줬는데도 하나만 스레드가 중단되고, 하나는 계속 진행이 됩니다.

이럴 땐 어떻게 해야할까요?

싱크로나이즈가 답이 아닌가요?

방법만 알려주시면 제가 혼자 해보고 싶어서 입코딩으로만 올렸습니다.

읽어주셔서 감사합니다.

  • 2017년 01월 06일에 작성됨
    해시코드를 사랑합니다

조회수 721


1 답변


공유 변수의 값을 확인하거나 변경하는 코드를 Critical Section 으로 변경해야 합니다.

Critical Section이란 간단히 말해서, 제한적으로 접근을 허용할 수 있는 구간을 말합니다. 통상 하나의 스레드만 접근할 수 있게할 때 사용합니다.

public class Shared {
    private static Shared instance = new Shared(); // 싱글톤 패턴의 인스턴스

    public static Shared getInstance() { return instance; }

    private int count;

    private Shared() {} // 싱글톤으로 하기 위해서 private 생성자로 함.

    public int getCount() { return count; }
    public void setCount(int count) { this.count = count; }
    public int increment() { return ++count; }
    public int decrement() { return --count; }
    public int increment(int x) { return (count+=x); }
    public int decrement(int x) { return (count-=x); }
}

공유의 예를 간단히 하기 위해서 싱글톤 패턴의 클래스를 예로 들었습니다. 위 Shared의 인스턴스( Shared.getInstance())를 여러개의 스레드가 공유할 경우에 count의 값의 변경이 스레드간에 동기화되지 않을 수 있습니다.

간단히 해결하는 방법은 다음과 같이 synchronized를 추가하는 방법이 있습니다.

public synchronized int getCount() ...;
public synchronized void setCount(int count) ...;

다른 방법은 java.util.concurrent 패키지에 있는 ReentrantLock 을 사용하시면 됩니다.

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // 락 설정. -- synchronized 키워드를 대체할 예정.

   public void m() {
     lock.lock();  // Critical 섹션의 시작
     try {
       // Critical 섹션 코드
     } finally {
       lock.unlock(); // Critical 섹션 해제
     }
   }
 }

  • 2017년 01월 06일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close