一个长度为10的StringBuffer对象sbMainScene代表主屏幕可见区域;一个长度为2的StringBuffer型数组sbBuffer[],其每个元素都是一长度为5的StringBuffer对象作为双缓冲区的代表。绘制缓冲区的操作变为,每次随机产生一个0至0x10之间的整数,用从它到倒数到0的十六进制表示来作为填充StringBuffer的内容。比如随机产生的数字为4,则新“绘制”的内容是“43210”;滚动卷轴的操作变为:用缓冲区的内容向sbMainScene左移,每左移一位输出一次sbMainScene的内容,这样每次输出的内容就好像是屏幕滚动的每一帧一样。测试程序如下:
import java.util.Random;
import BiBuffer.BiBuffer;
public class TestBiBuffer {
static int counter=-1; //随机产生数字的寄存器
static String numChars="0123456789ABCDEF"; //作为数字对应字符的查找表之用
static StringBuffer sbMainScene;
static Random rand;
public static void main(String[] args) {
rand=new Random(System.currentTimeMillis());
//初始化“可见区域”
sbMainScene=new StringBuffer(10);
for (int i=0; i<10; i++) sbMainScene.append(" ");
//建立缓冲
StringBuffer[] sbBuffer=new StringBuffer[2];
for (int i=0; i<2; i++) sbBuffer[i]=new StringBuffer(5);
//用创建好的缓冲数组建立乒乓缓冲对象
final BiBuffer buffers=new BiBuffer(sbBuffer);
//读取者线程,负责“卷轴滚动”
Thread tReader=new Thread() {
public void run() {
Object buf;
StringBuffer s;
while (true) {
//为“读”请求一个缓冲
buf=buffers.openBuf('r');
s=(StringBuffer)buf;
for (int i=0; i<s.length(); i++) {
//将缓冲区内容左移入可见区域
sbMainScene.deleteCharAt(0);
sbMainScene.append(s.charAt(i));
//每移一位输出一次可见区域内容
System.out.println(sbMainScene);
}
//关闭
buffers.closeBuf(buf);
}
}
};
Thread tWriter=new Thread() {
public void run() {
Object buf;
StringBuffer s;
while(true) {
//为“写”请求一个缓冲
buf=buffers.openBuf('w');
s=(StringBuffer)buf;
s.delete(0, s.length());
for (int i=0; i<s.capacity(); i++) {
//若倒数完毕,重新产生一个随机非负整数
if (counter==-1) counter=rand.nextInt(numChars.length());
//将数字对应字符连缀进缓冲区,计数值减1
s.append(numChars.charAt(counter--));
}
//关闭
buffers.closeBuf(buf);
}
}
};
tReader.start(); tWriter.start();
}
}
执行后就可以看到效果了。截取某次运行的一段输出结果看看:
03210DCBA9
3210DCBA98
210DCBA987
10DCBA9876
0DCBA98765
DCBA987654
CBA9876543
BA98765432
A987654321
9876543210
8765432106
7654321065
6543210654
5432106543
4321065432
3210654321
2106543210
1065432109
0654321098
6543210987
5432109876
4321098765
3210987654
2109876543
1098765432
0987654321
9876543210
8765432106
……
说明功能是正确无误的。
至于上文说到的简化使用的设计,其实无非就是增加了一个接口的定义和两个方法:
BiBufferAccessor.java :
public interface BiBufferAccessor {
public abstract void doWrite(Object buf);
public abstract void doRead(Object buf);
}
BiBuffer.java :
//……
public void write(BiBufferAccessor w) {
Object buf;
buf=openBuf('w');
w.doWrite(buf);
closeBuf(buf);
}
public void read(BiBufferAccessor r) {
Object buf;
buf=openBuf('r');
r.doRead(buf);
closeBuf(buf);
}
}
这样一来,可以让对缓冲对象进行操作的类实现doWrite和doRead方法,把自身作为参数传入,即可省出要写openBuf和closeBuf的麻烦,更重要的是确保不会写出错误的代码(openBuf没有匹配的closeBuf)。