Created StringBuilders thread local holder and using thread local StringBuilder in Log4jAdapterLabelPrinter that can be shared between many threads.

This commit is contained in:
tomasz.kowalczewski committed 2021-10-20 23:44:04 +02:00
1 parent 4947bff2b0
commit 1a7694a89b
3 files changed
+69 -1

No files matched your search

@@ -4,6 +4,7 @@ import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.pattern.LiteralPatternConverter;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import pl.tkowalcz.tjahzi.log4j2.utils.StringBuilders;
import java.util.List;
import java.util.function.Consumer;
@@ -11,7 +12,6 @@ import java.util.function.Consumer;
@SuppressWarnings("ForLoopReplaceableByForEach")
public class Log4jAdapterLabelPrinter implements LabelPrinter {
private final StringBuilder outputBuffer = new StringBuilder();
private final List<PatternFormatter> formatters;
public Log4jAdapterLabelPrinter(List<PatternFormatter> formatters) {
@@ -0,0 +1,13 @@
package pl.tkowalcz.tjahzi.log4j2.utils;
public class StringBuilders {
private static final ThreadLocal<StringBuilder> THREAD_LOCAL = ThreadLocal.withInitial(StringBuilder::new);
public static StringBuilder threadLocal() {
StringBuilder result = THREAD_LOCAL.get();
result.setLength(0);
return result;
}
}
@@ -0,0 +1,55 @@
package pl.tkowalcz.tjahzi.log4j2.utils;
import org.junit.jupiter.api.Test;
import java.util.concurrent.atomic.AtomicReference;
import static org.assertj.core.api.Assertions.assertThat;
class StringBuildersTest {
@Test
void shouldClearBufferBeforeUse() {
// Given
StringBuilder stringBuilder = StringBuilders.threadLocal();
stringBuilder.append("abc");
// When
StringBuilder actual = StringBuilders.threadLocal();
// Then
assertThat(actual.toString()).isEmpty();
}
@Test
void shouldReturnSameBufferInsideSameThread() {
// When
StringBuilder stringBuilder1 = StringBuilders.threadLocal();
StringBuilder stringBuilder2 = StringBuilders.threadLocal();
// Then
assertThat(stringBuilder1).isSameAs(stringBuilder2);
}
@Test
void shouldReturnDifferentBufferInsideDifferentThreads() throws InterruptedException {
// Given
AtomicReference<StringBuilder> captor1 = new AtomicReference<>();
AtomicReference<StringBuilder> captor2 = new AtomicReference<>();
// When
Thread thread1 = new Thread(() -> captor1.set(StringBuilders.threadLocal()));
thread1.start();
thread1.join();
Thread thread2 = new Thread(() -> captor2.set(StringBuilders.threadLocal()));
thread2.start();
thread2.join();
// Then
assertThat(captor1.get()).isNotNull();
assertThat(captor2.get()).isNotNull();
assertThat(captor1.get()).isNotSameAs(captor2.get());
}
}