문제

나는 유형의 카운터가 필요하다 long 다음 요구 사항/사실 :

  • 카운터를 증가시키는 데 가능한 한 적은 시간이 걸립니다.
  • 카운터는 하나의 스레드에 의해서만 작성됩니다.
  • 카운터에서 읽는 것은 다른 스레드에서 수행됩니다.
  • 카운터는 정기적으로 증가하지만 (초당 수천 번) 5 초마다 한 번만 읽습니다.
  • 정확한 정확도는 필수적이지 않으며 카운터 크기에 대한 대략적인 아이디어 만 충분합니다.
  • 카운터는 절대 제거되지 않고 감소합니다.

이러한 요구 사항에 따라 카운터를 어떻게 구현하기로 선택 하시겠습니까? 간단하게 long, a volatile long 또는 사용 AtomicLong? 왜요?

현재 나는 a volatile long 그러나 또 다른 접근 방식이 더 나을 지 궁금했습니다. 나는 또한 그렇게함으로써 오랫동안 오랫동안 증가하고 있습니다 ++counter 반대로 counter++. 과제가 수행되지 않기 때문에 이것이 더 효율적입니까 (다른 곳에서 믿게되었으므로)?

도움이 되었습니까?

해결책

이러한 요구 사항 세트가 주어지면 i 생각한다 그 a volatile 오랫동안 충분해야합니다. 카운터는 비volatile 길지만 독자는이 경우에도 오래된 정보를 읽고있을 수 있습니다.

한 가지 문제는 a를 읽고 쓰는 것입니다 long ~이다 ~ 아니다 필수의 원자력,, JVM 사양 선언되지 않은 경우 volatile. 이는 쓰기 스레드가 값의 한 부분을 업데이트하는 동안 값을 읽는다면 읽기 스레드가 값을 읽으면 거의 가상의 가치를 얻을 수 있음을 의미합니다.

차이 ++counter 그리고 counter++ ~이다 아마 JVM이 표현식의 값이 더 이상 사용되지 않으며이 경우에는 두 사람이 동일하다는 것을 인식 할 수 있으므로 관련이 없습니다.

다른 팁

Java 8에서는 스레드 경합이 높은 Atomiclong보다 훨씬 우수한 Longadder를 사용하십시오.

Longadder Javadoc :

이 클래스는 여러 스레드가 세밀한 동기화 제어가 아닌 통계 수집과 같은 목적으로 사용되는 공통 합을 업데이트 할 때 일반적으로 원자력보다 바람직합니다. 낮은 업데이트 경합에서 두 클래스는 비슷한 특성을 가지고 있습니다. 그러나 높은 경합에서 공간 소비가 더 높은 비용 으로이 클래스의 예상 처리량이 상당히 높습니다.

프로그램의 가동 시간 요구 사항은 무엇입니까? 비 휘발성 INT 및 Racy-Reads로 할 수 있습니까?

10^4 증분 / 초는 100 USEC마다 1입니다. 효율성은 문제가되지 않지만 원자력이 될 수 있습니다. 당신은 그것의 사본 2 부가있을 수 있으며, 그것을 읽을 때, 그것들이 같지 않으면 다시 읽으십시오.

이것 기사 카운터를 구현할 수있는 가능한 방법에 대해 이야기합니다.이 구현이 당신에게 효과가 있다고 생각합니다.

class LessNaiveVolatieIdGenerator {
private static volatile long id = 0;
public static long nextId() {
    long nextId = (id = id + 1); // or nextId = id++;
    return nextId;
}

}

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top