This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 47d861808a Replace `synchronized` with locks in JTL (#2725)
47d861808a is described below

commit 47d861808ad8466d15a8b41fb4c5236d438c782e
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Tue Jul 9 20:47:12 2024 +0200

    Replace `synchronized` with locks in JTL (#2725)
---
 .../JsonTemplateLayoutNullEventDelimiterTest.java  | 40 ++++++++++++++++++----
 .../template/json/resolver/TimestampResolver.java  | 28 +++++++++++++--
 2 files changed, 59 insertions(+), 9 deletions(-)

diff --git 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutNullEventDelimiterTest.java
 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutNullEventDelimiterTest.java
index 3c9c69f305..e17054c407 100644
--- 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutNullEventDelimiterTest.java
+++ 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutNullEventDelimiterTest.java
@@ -25,6 +25,8 @@ import java.io.InputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
@@ -108,11 +110,13 @@ class JsonTemplateLayoutNullEventDelimiterTest {
 
     private static final class TcpServer extends Thread implements 
AutoCloseable {
 
+        private final Lock lock = new ReentrantLock();
+
         private final ServerSocket serverSocket;
 
         private final ByteArrayOutputStream outputStream;
 
-        private volatile int totalReadByteCount = 0;
+        private int totalReadByteCount = 0;
 
         private volatile boolean closed = false;
 
@@ -136,9 +140,12 @@ class JsonTemplateLayoutNullEventDelimiterTest {
                         final int readByteCount = inputStream.read(buffer);
                         if (readByteCount != -1) {
                             LOGGER.info("Received bytes {}.", () -> 
Hex.encodeHex(buffer, 0, readByteCount, false));
-                            synchronized (this) {
+                            lock.lock();
+                            try {
                                 totalReadByteCount += readByteCount;
                                 outputStream.write(buffer, 0, readByteCount);
+                            } finally {
+                                lock.unlock();
                             }
                         } else {
                             break;
@@ -159,16 +166,35 @@ class JsonTemplateLayoutNullEventDelimiterTest {
             return serverSocket.getLocalPort();
         }
 
-        public synchronized byte[] getReceivedBytes() {
-            return outputStream.toByteArray();
+        public byte[] getReceivedBytes() {
+            lock.lock();
+            try {
+                return outputStream.toByteArray();
+            } finally {
+                lock.unlock();
+            }
         }
 
-        public synchronized int getTotalReadByteCount() {
-            return totalReadByteCount;
+        public int getTotalReadByteCount() {
+            lock.lock();
+            try {
+                return totalReadByteCount;
+            } finally {
+                lock.unlock();
+            }
         }
 
         @Override
-        public synchronized void close() {
+        public void close() {
+            lock.lock();
+            try {
+                unsynchronizedClose();
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        private void unsynchronizedClose() {
             if (closed) {
                 throw new IllegalStateException("shutdown has already been 
invoked");
             }
diff --git 
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TimestampResolver.java
 
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TimestampResolver.java
index 4974de9057..f023f603aa 100644
--- 
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TimestampResolver.java
+++ 
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TimestampResolver.java
@@ -18,6 +18,8 @@ package 
org.apache.logging.log4j.layout.template.json.resolver;
 
 import java.util.Locale;
 import java.util.TimeZone;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.time.Instant;
 import org.apache.logging.log4j.core.time.MutableInstant;
@@ -257,6 +259,8 @@ public final class TimestampResolver implements 
EventResolver {
 
     private static final class PatternResolver implements EventResolver {
 
+        private final Lock lock = new ReentrantLock();
+
         private final PatternResolverContext patternResolverContext;
 
         private PatternResolver(final PatternResolverContext 
patternResolverContext) {
@@ -264,7 +268,16 @@ public final class TimestampResolver implements 
EventResolver {
         }
 
         @Override
-        public synchronized void resolve(final LogEvent logEvent, final 
JsonWriter jsonWriter) {
+        public void resolve(final LogEvent logEvent, final JsonWriter 
jsonWriter) {
+            lock.lock();
+            try {
+                unsynchronizedResolve(logEvent, jsonWriter);
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        private void unsynchronizedResolve(final LogEvent logEvent, final 
JsonWriter jsonWriter) {
 
             // Format timestamp if it doesn't match the last cached one.
             final boolean instantMatching = 
patternResolverContext.formatter.isInstantMatching(
@@ -337,10 +350,21 @@ public final class TimestampResolver implements 
EventResolver {
 
     private abstract static class EpochResolver implements EventResolver {
 
+        private final Lock lock = new ReentrantLock();
+
         private final EpochResolutionRecord resolutionRecord = new 
EpochResolutionRecord();
 
         @Override
-        public synchronized void resolve(final LogEvent logEvent, final 
JsonWriter jsonWriter) {
+        public void resolve(final LogEvent logEvent, final JsonWriter 
jsonWriter) {
+            lock.lock();
+            try {
+                unsynchronizedResolve(logEvent, jsonWriter);
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        private void unsynchronizedResolve(final LogEvent logEvent, final 
JsonWriter jsonWriter) {
             final Instant logEventInstant = logEvent.getInstant();
             if (logEventInstant.equals(resolutionRecord.instant)) {
                 jsonWriter.writeRawString(resolutionRecord.resolution, 0, 
resolutionRecord.resolutionLength);

Reply via email to