2014-11-25 2 views
-1

내가 기아 문제를 방지 할 수있는 방법은 수면을 쓰는 시뮬레이션 방법으로 인한 것입니까? 스레드를 오랫동안 잠자기 상태로두면 잠시 동안 잠자기 한 것보다 절대로 쓸 수 없습니다.기아 스레드

이 프로그램은 my_file 클래스의 쓰기 메서드에 지속적으로 액세스하는 많은 스레드로 구성되어 있습니다. 모든 스레드가 공유하지만 한 번에 하나의 스레드 만 파일에 쓸 수 있습니다.

public class My_File { 

    private boolean writing = false; 

    public synchronized void write() { 
    String name = Thread.currentThread().getName(); 
    System.out.println(name +" writing "); 
    try{ 
     Thread.sleep((int)(Math.random()*3000)); 
    } catch(InterruptedException e){ 
     e.printStackTrace(); 
    } 
    System.out.println(name +" writing end "); 
    } 
} 

나는이 문제를 가지고, 나는 많은 스레드에 의해 공유 파일을 많이 가지고 있지만, 아무것도하지 않고 모든 스레드가 경우에 파일에 기록하려고 기입 방법 수면에 의해 시뮬레이션, 난 몰라 이 상황에서 기아를 막을 수있는 방법은 무엇입니까?

+0

당신은이 질문을 수정해야합니다. 그런데'synchronized' 키워드를 사용하지 마십시오. 일반적으로 안전하지 않기 때문에, 그리고 대부분의 다른 경우에는 반드시 필요한 것은 아니지만 우아하지 않습니다. – Powerslave

+0

동기화 대신 사용할 수있는 항목은 무엇입니까? 명확하지 않은 점은 무엇입니까? – alexander

+0

단어가 무작위에 가깝기 때문에 문제/질문이 무엇인지 잘 모르겠습니다. 'synchronized'를 사용하는 대신에, 예를 들어 클래스 내에서'BlockingDeque'를 사용하여 로거를 래핑 할 수 있습니다 (로거 프레임 워크를 사용하고 있고 로거 구현이 아닌 것으로 가정). 전용 로깅 스레드가 대기열을 로거에 전달하십시오. 'BlockingDeque'는 스레드가 가득 찼을 때 항상 차단되므로 스레드로부터 안전합니다. 로깅 시도 시간이 초과되면 다시 시도하십시오. 또한 다른 동시 수집 또는 솔루션이 있습니다. – Powerslave

답변

1

일정한 처리량을 보장하려면 공정한 재진입 성이 필요합니다. 귀하의 경우는 버그 설명에서

"단순"동기화 "잠금은 대기중인 스레드에 의해 잠금을 얻는 순서를 보장하지 않으므로"마지막으로 입력 한 "스레드가 잠금을 얻는 경우, Logback 버그 268과 매우 유사합니다. "처음 입력"동안 스레드 ... 아주 긴 시간 동안 "

"를 기다릴 수 나는 java.util.concurrent.locks.ReentrantLock는 "공정"모드에서 작업으로이 자물쇠를 교체하려고 상황이 크게 좋아졌습니다! "

코드 변경 사항은 github commit에 표시됩니다. 이 패턴에

class MyFileUnfair { 

    private final Object writeLock = new Object(); 

    public void write(byte[] data) { 

     synchronized(writeLock) { 
      writeToFile(data); 
     } 
    } 

    private void writeToFile(byte[] data) { 
     // write to file 
    } 
} 

: 의사 코드에서이 패턴을 변경 그것이 현재의 형태로 해석 할 수없는 그대로

class MyFileFair { 

    private final ReentrantLock writeLock = new ReentrantLock(true); 

    public void write(byte[] data) { 

     writeLock.lock(); 
     try { 
      writeToFile(data); 
     } finally { 
      writeLock.unlock(); 
     } 
    } 

    private void writeToFile(byte[] data) { 
     // write to file 
    } 
}