Refactor G2DRenderer and G2DRendererControl to replace Semaphore with ReentrantReadWriteLock for improved concurrency management

This commit is contained in:
extio-de
2025-12-21 17:27:21 +01:00
parent 8fcce2368b
commit 30cd1ead46
2 changed files with 17 additions and 20 deletions

View File

@@ -9,8 +9,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.imageio.ImageIO;
@@ -36,7 +37,7 @@ public class G2DRenderer implements Renderer {
private static final Logger LOGGER = LoggerFactory.getLogger(G2DRenderer.class);
private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(3);
private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(2);
private final RingBuffer<Integer> fpsHistory = new RingBuffer<>(90);
@@ -54,7 +55,7 @@ public class G2DRenderer implements Renderer {
private long frameDur;
private final Semaphore semaphore = new Semaphore(1);
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);
private String title;
@@ -63,6 +64,7 @@ public class G2DRenderer implements Renderer {
public G2DRenderer() {
LOGGER.info("ctor");
System.setProperty("java.awt.headless", "false");
System.setProperty("sun.java2d.uiScale", "1");
System.setProperty("awt.nativeDoubleBuffering", "true");
System.setProperty("awt.useSystemAAFontSettings", "on");
@@ -100,7 +102,7 @@ public class G2DRenderer implements Renderer {
@Override
public void run(final List<RenderingBo> renderingBOs) throws InterruptedException {
try {
this.semaphore.acquire();
this.rwLock.readLock().lockInterruptibly();
try {
if (this.mainFrame == null) {
return;
@@ -180,7 +182,7 @@ public class G2DRenderer implements Renderer {
}
}
finally {
this.semaphore.release();
this.rwLock.readLock().unlock();
}
}
catch (final G2DRendererWindowNotInitializedException e) {
@@ -291,8 +293,12 @@ public class G2DRenderer implements Renderer {
this.mainFrame = mainFrame;
}
public Semaphore getSemaphore() {
return this.semaphore;
public Lock getReadLock() {
return this.rwLock.readLock();
}
public Lock getWriteLock() {
return this.rwLock.writeLock();
}
@Override

View File

@@ -49,12 +49,7 @@ public class G2DRendererControl implements RendererControl {
@Override
public void applyVideoOptions() {
final Runnable run = () -> {
try {
this.renderer.getSemaphore().acquire();
}
catch (final InterruptedException e) {
return;
}
this.renderer.getWriteLock().lock();
try {
if (this.renderer.getMainFrame() != null) {
this.renderer.getMainFrame().unregisterFullScreenWindow();
@@ -95,7 +90,7 @@ public class G2DRendererControl implements RendererControl {
this.updateViewPort(false, false);
}
finally {
this.renderer.getSemaphore().release();
this.renderer.getWriteLock().unlock();
this.videoOptionsAppliedAt = System.currentTimeMillis();
}
};
@@ -162,11 +157,7 @@ public class G2DRendererControl implements RendererControl {
final Runnable run = () -> {
if (lockRenderer) {
try {
this.renderer.getSemaphore().acquire();
}
catch (final InterruptedException e) {
}
this.renderer.getWriteLock().lock();
}
try {
this.updateAbsoluteViewportPortDimension();
@@ -176,7 +167,7 @@ public class G2DRendererControl implements RendererControl {
}
finally {
if (lockRenderer) {
this.renderer.getSemaphore().release();
this.renderer.getWriteLock().unlock();
}
}
};