Refactor G2DRenderer and G2DRendererControl to replace Semaphore with ReentrantReadWriteLock for improved concurrency management
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user