对于下面的示例代码,如何从synchronized
迁移到ReentrantLock
?
下面是重构后的代码
public final class ControllerCell {
public final int tableSize;
private final ObjectCell cells[][];
private final TGS_ShapeDimension<Integer> cellSize;
private final float jpeg_quality;
public static ControllerCell of(float jpeg_quality, int tableSize) {
return new ControllerCell(jpeg_quality, tableSize);
}
private ControllerCell(float jpeg_quality, int tableSize) {
this.jpeg_quality = jpeg_quality;
this.tableSize = tableSize;
cellSize = new TGS_ShapeDimension(0, 0);
cells = new ObjectCell[tableSize][tableSize];
}
final public void processImage(ControllerInput cInput) {
cellSize.width = cInput.screenSize.width / tableSize;
cellSize.height = cInput.screenSize.height / tableSize;
for (var i = 0; i < tableSize; i++) {
for (var j = 0; j < tableSize; j++) {
if (cells[i][j] == null) {
cells[i][j] = new ObjectCell(jpeg_quality);
}
var subw = (i == tableSize - 1) ? (cellSize.width + (cInput.screenSize.width % cellSize.width)) : cellSize.width;
var subh = (j == tableSize - 1) ? (cellSize.height + (cInput.screenSize.height % cellSize.height)) : cellSize.height;
var subimage = cInput.screenShot().getSubimage(i * cellSize.width, j * cellSize.height, subw, subh);
synchronized (cells[i][j]) {
cells[i][j].update(subimage);
}
}
}
}
}
以下是原始代码.要下载click here个
类:TileManager
/**
*
* @author heic
*/
package hk.haha.onet.ajaxvnc;
import java.awt.image.*;
public class TileManager {
private boolean DEBUG = true;
public final int MAX_TILE = 10;
private Tile tiles[][];
private int numxtile;
private int numytile;
private int tilewidth;
private int tileheight;
private int screenwidth;
private int screenheight;
/** Creates a new instance of TileManager */
public TileManager() {
tiles = new Tile[MAX_TILE][MAX_TILE];
numxtile = MAX_TILE;
numytile = MAX_TILE;
setSize(640, 480);
}
public void setSize(int sw, int sh) {
screenwidth = sw;
screenheight = sh;
tilewidth = screenwidth / numxtile;
tileheight = screenheight / numytile;
}
public void processImage(BufferedImage image, int x, int y)
{
BufferedImage subimage;
int subw, subh;
boolean changed;
numxtile = x;
numytile = y;
setSize(screenwidth, screenheight);
for (int i=0; i < numxtile; i++) {
for (int j=0; j < numytile; j++) {
if (tiles[i][j]==null) tiles[i][j] = new Tile();
if (i == numxtile-1)
subw = tilewidth + (screenwidth % tilewidth);
else
subw = tilewidth;
if (j == numytile-1)
subh = tileheight + (screenheight % tileheight);
else
subh = tileheight;
subimage = image.getSubimage(i*tilewidth, j*tileheight, subw, subh);
synchronized (tiles[i][j]) {
changed = tiles[i][j].updateImage2(subimage);
if (DEBUG) {
if (changed) System.out.println(getClass().getName() + ": [" + i + "," + j + "] Changed. ["+tiles[i][j].fileSize()+"]");
}
}
}
}
}
}
类别:瓷砖
/**
*
* @author heic
*/
package hk.haha.onet.ajaxvnc;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.ImageObserver;
import java.awt.image.PixelGrabber;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import javax.imageio.ImageIO;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.util.Iterator;
import javax.imageio.metadata.*;
public class Tile {
private boolean DEBUG = false;
private ByteArrayOutputStream stream;
private Adler32 checksum;
private long version;
private boolean dirty;
private int width;
private int height;
private static ImageWriter imgwriter;
private static ImageWriteParam iwp;
/** Creates a new instance of Tile */
public Tile() {
stream = new ByteArrayOutputStream();
checksum = new Adler32();
version = 0;
dirty = true;
width = 0;
height = 0;
// create image writer
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
imgwriter = (ImageWriter)iter.next();
iwp = imgwriter.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(Config.jpeg_quality); // an integer between 0 and 1
}
private IIOMetadata getIIOMetadata(BufferedImage image, ImageWriter imageWriter, ImageWriteParam param) {
ImageTypeSpecifier spec = ImageTypeSpecifier.createFromRenderedImage(image);
IIOMetadata metadata = imageWriter.getDefaultImageMetadata(spec,param);
return metadata;
}
private void writeImage(BufferedImage image, OutputStream outs)
{
try {
/* ImageIO.write(image, "JPG", outs);*/
width = image.getWidth();
height = image.getHeight();
ImageOutputStream ios = ImageIO.createImageOutputStream(outs);
imgwriter.setOutput(ios);
IIOMetadata meta = getIIOMetadata(image, imgwriter, iwp);
imgwriter.write(meta, new IIOImage(image, null, meta), iwp);
ios.flush();
}
catch (Exception e) {
e.printStackTrace();
}
}
public boolean updateImage2(BufferedImage image)
{
long oldsum;
oldsum = checksum.getValue();
//calcChecksum(image);
calcChecksum2(image);
if (oldsum != checksum.getValue()) {
if (DEBUG) System.out.println(getClass().getName() + ": Version changed [" + stream.size() +"]");
stream.reset();
writeImage(image, stream);
version++;
dirty = true;
return true;
}
else {
if (DEBUG) System.out.println(getClass().getName() + ": Version unchange");
return false;
}
}
}
其动机是利用Java 21+中的虚拟线程.引用JEP 444: Virtual Threads
句话:
通过修改
synchronized
个频繁运行的块或方法来避免频繁和长时间的锁定,并保护可能较长的I/O操作而改用java.util.concurrent.locks.ReentrantLock
.