Logback 포맷
14:18:17.635 [Name of Thread] INFO c.e.NameOfLogger - Log message
java.util.logging 포맷
Feb 08, 2017 2:09:19 PM com.example.NameOfLogger nameOfMethod
INFO: Log message
Log4j 포맷
2017-02-08 14:16:29,651 [Name Of Thread] INFO com.example.NameOfLogger - message
ThreadLocal
필드를 이용해 스트링 → 바이트 변환 시 버퍼를 재사용하며 객체를 재사용한다.ByteBuffer
클래스가 존재
ByteBuffer
의 문제
DirectBuffer
인터페이스: 버퍼에서 읽기만 가능하며 최상위 계층에 위치MutableDirectBuffer
인터페이스: DirectBuffer
를 상속하여 버퍼에 쓰기도 가능AtomicBuffer
인터페이스: MutableDirectBuffer
를 상속하여 메모리 엑세스 순서까지 보장UnsafeBuffer
클래스: Unsafe
를 이용해 AtomicBuffer를 구현한 클래스get
메서드로 하부 데이터를 가져올 수 있다. (ex. getLong(int index)
)put
메서드로 버퍼 특정 위치에 값을 넣을 수도 있다.int
또는 long
형 배열에 기반한 리스트 구현체를 여러 제공한다.ArrayListUtil
을 이용하면 리스트 순서는 안맞지만 ArrayList
에서 신속하게 원소를 제거할 수 있다.java.util.Queue
인터페이스를 준수org.agrona.concurrent.Pipe
인터페이스도 존재org.agrona.concurrent.AbstractConcurrentArrayQueue
OneToOneConcurrentArrayQueue
ManyToManyConcurrentArrayQueue
while
루프에서 Unsafe.compareAndSwapLong
을 사용해 락-프리하게 업데이트할 수 있다.ManyToOneConcurrentArrayQueue
comapreAndSwap
을 감싼 while
루프가 필요org.agrona.concurrent.RingBuffer
DirectBuffer
를 이용해 메시지 오프-힙 저장소를 관리OneToOneRingBuffer
, ManyToOneRingBufer
onMessage()
메서드로 콜백된다.1// 발행자
final MediaDriver driver = MediaDriver.lanunch();
final Aeron.Context ctx = new Aeron.Context();
try (Publication publication = aeron.addPublication(CHANNEL, STREAM_ID)) {
// ...
final long result = pulication.offer(BUFFER, 0, messageBytes.length);
}
// 구독자
final FragmentHandler fragmentHandler =
SamplesUtil.printStringMessage(STREAM_ID);
try (Aeron aeron = Aeron.connect(ctx);
Subscription subscription = aeron.addSubscription(CHANNEL, STREAM_ID)) {
SamplesUtil.subscriberLoop(
fragment, FRAGMENT_COUNT_LIMIT, running
).accept(subscription);
}