📄 pooltest.java
字号:
import contest.*;
/*
PoolMan中包含一个与竞态条件有关的共享资源冲突Bug,
PoolTest类使用contest提供的同步动态测试功能,
可以发现这个Bug
*/
public class PoolTest
{
public static void main(String[] args)
{
PoolMan pool = new PoolMan(10);
PoolManThread t1 = new PoolManThread(pool);
PoolManThread t2 = new PoolManThread(pool);
TestManager test = TestManager.getInstance();
test.addThread(t1, "Thread1");
test.addThread(t2, "Thread2");
test.addEvent("Event1", 1000);
test.start();
}
}
// 对象池管理类的模拟,可以为不同的线程分配对象池pool中
// 的对象,分配规则是不同线程不能同时获得同一个对象。
// 但PoolMan类的getObject()方法中有一个Bug,可能造成某些
// 情况下,不同线程获得同一个对象。
class PoolMan
{
private boolean[] pool;
public PoolMan(int size)
{
pool = new boolean[size];
}
public int getObject()
{
int i;
synchronized (this)
{
for (i = 0; i < pool.length; i++)
if (!pool[i])
{
// pool[i] = true; // 下面那行错误代码的正确位置
break;
}
}
// 下面插入的代码可以令不同的线程在这里同步,然后打印输出
// 线程获得的对象序号,因为下面的错误代码,线程同步后,不
// 同线程获得的对象序号相同
TestManager.waitFor("Event1");
System.out.println(Thread.currentThread().getName() + ": " + i);
if (i < pool.length)
{
pool[i] = true; // 错误!这行代码应置于前面synchronized结构中
return i;
}
else
return -1;
}
public boolean releaseObject(int obj)
{
int i;
synchronized (this)
{
for (i = 0; i < pool.length; i++)
if (pool[i] && i == obj)
{
pool[i] = false;
break;
}
}
if (i < pool.length)
return true;
else
return false;
}
}
class PoolManThread
extends Thread
{
PoolMan pool;
public PoolManThread(PoolMan pool)
{
this.pool = pool;
}
public void run()
{
int obj = pool.getObject();
try {sleep(1000);}
catch (Exception e){}
pool.releaseObject(obj);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -