导入
用静态对象数组可以达到“可变用例数目”的目的,用一个静态整形num记录用例数量,保证用例数量不超出范围,在这里需要注意多线程环境下共享变量num的同步问题,需要加锁访问num。
那么当实例数量达到极限,不允许创建时,如何访问已创建的实例呢?总是访问最新创建的?这很不公平。采用静态变量p(以自增取模的方式)指挥哪个用例将被访问,达到“雨露均沾”的效果。同样的,p也是共享变量,需要加锁控制访问。
代码:
package singleton2;
public class Singleton {
private static Singleton[] singleton=new Singleton[3];//约定用例数目最多不超过3个
private static Integer num=0;//记录实例数量
private static Integer p=-1;//控制哪个实例将被访问
private Singleton() {
}
public static Singleton getIntance() {
int my;//局部变量,每个线程在自己的线程栈里存储,记录访问的实例索引。
if(num<3) {//若实例数量未达极限,则创建
synchronized (num) {
if(num<3) {
singleton[num]=new Singleton();
System.out.println(num+" was born");
num++;
}
}
}
synchronized (p) {//公平的挑一个被访问的实例
p=(p+1)%3;
my=p;
}
System.out.println(my+" was used");
return singleton[my];
}
}
测试结果
- 下面创建了四个线程去访问实例,测试是否保证全局仅创建了特定数量(3)的实例:
查看结果,仅创建了特定数量(3)的实例,符合预期
- 当多个线程想要访问特定数量的实例时,测试多个实例的访问是公平的:
可以看到创建了9个线程去访问限定数量为3的实例,每个实例均被访问3次,很公平。