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

View File

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