vector虽然所有方法都是同步的,线程安全的。但是这个对于我们编程也不是一定线程安全的。当然这是有条件的。
比如有一个
Vector vectorOfEnemyTank; 变量,这个变量是对象属性级别的。
一个线程方法
public boolean isTouchOtherTanke()
{
.......
EnemyTank ee = getEnemyTankOfCount.get(i);
.........
}
这里的getEnemyTankOfCount变量是vectorOfEnemyTank变量的引用, 每创建一个对象,他都指向相同的同一个向量空间,这个向量空间就是vectorOfEnemyTank。
但是如果现在有十个线程,同时调用isTouchOtherTanke方法,那么相当于十个线程同时操作同一个向量空间,每个线程都是通过getEnemyTankOfCount向量引用操作同一个向量空间。那么这里可能因为线程1对vectorOfEnemyTank的向量空间操作,而线程2并不知道这个情况,那么发生遍历Vector的时候就可能发生数组越界的错误。
综上结语:对vector向量元素的操作方法是线程安全的,但是当把这些方法组合在一起,在两个方法被执行的间隙,可能由其他线程获得对象锁,从而改变了属性的状态;这个时候在执行线程的另外一个方法可能就会发生错误了。比如上面这个例子可能发生的错误是数组越界。
//源码如下
/**
* @author pengrong
* @return
* @功能:被坦克调用以判定坦克和面板中其他坦克是不是碰撞了;
* @author pengrong 重大功能更改,这个函数表示的是面板上所有的坦克线程都会调用的。
* 访问的是面板上的同一个集合变量 Vector<EnemyTank> vectorOfEnemyTank。注意哦是同一个啊,所以要同步,不然会发生数组越界的风险
* 初步打算是把这个方法改造成类同步规则,所以每个坦克都要传递两个参赛,1、代表自己的坦克引用,保存有所有面板坦克的vector变量。
*/
public synchronized static boolean isTouchOtherTank(EnemyTank et, Vector<EnemyTank> getEnemyTankOfCount)
{
if (getEnemyTankOfCount ==null) {
return false;
}
boolean isTrue =false;
int X1,Y1,X2,Y2;
switch ( et.getDierction() )
{
//我的坦克向上
case 0:
/**
* 定义X1,Y1;用于界定坦克的另外三个点的坐标
*/
X1 = et.getAxisX() + 33;
Y1 = et.getAxisY() + 53;
for (int i = 0; i < getEnemyTankOfCount.size(); i++)
{
//取到的坦克元素可能是自己
EnemyTank ee = getEnemyTankOfCount.get(i);
//如果ee的方向是往上或者往下的
if ( (ee.getDierction() ==0) || (ee.getDierction() == 2))
{
X2 =ee.getAxisX() +33;
Y2 =ee.getAxisY() +53;
}
else
{
X2 = ee.getAxisX() + 53;
Y2 = ee.getAxisY() + 33;
}
/**
* 如果坦克ee不是自己,同时还活着
*/
if ((ee != et) && (ee.isLive() ==true) )
{
/**
* 根据 我方坦克的上面左右两个顶点和坦克相比较得出是否相撞,并且改变方向
*/
//待比较坦克方向是向上/向下/想左/向右的
//从坦克向上方向判断是否有与之相撞
if ( ( et.getAxisX() >= ee.getAxisX() ) && ( et.getAxisX() <= X2 ) &&
( et.getAxisY() >= ee.getAxisY() ) && ( et.getAxisY() <= Y2 ) )
{
isTrue =true;
}
if ( ( X1 >= ee.getAxisX() ) && ( X1 <= X2 ) &&
( et.getAxisY() >= ee.getAxisY() ) && ( et.getAxisY() <= Y2 ) )
{
isTrue =true;
}
//从坦克的下方判断是否有与之相撞的坦克
if ( ( et.getAxisY() < ee.getAxisY() ) && ( ee.getAxisY() < Y1 ) )
{
isTrue =true;
}
//如果相撞了才需要设置坦克的新方向。这一点需要注意;设置自己方向改变
if ( isTrue == true )
{
//this.setDierction(2);
}
}
}
break;
//我方坦克向下
case 2:
/**
* 定义X1,Y1;用于界定坦克的另外三个点的坐标
*/
X1 = et.getAxisX() + 33;
Y1 = et.getAxisY() + 53;
for (int i = 0; i < getEnemyTankOfCount.size(); i++)
{
//取到的坦克元素可能是自己
EnemyTank ee = getEnemyTankOfCount.get(i);
//如果ee的方向是往上或者往下的
if ( (ee.getDierction() ==0) || (ee.getDierction() == 2))
{
X2 =ee.getAxisX() +33;
Y2 =ee.getAxisY() +53;
}
else
{
X2 = ee.getAxisX() + 53;
Y2 = ee.getAxisY() + 33;
}
/**
* 如果坦克ee不是自己,同时还活着
*/
if ((ee != et) && (ee.isLive() ==true) )
{
/**
* 根据 我方坦克的上面左右两个顶点和坦克相比较得出是否相撞,并且改变方向
*/
//待比较坦克方向是向上/向下/想左/向右的
//从坦克前进方向判断
if ( ( et.getAxisX() >= ee.getAxisX() ) && ( et.getAxisX() <= X2 ) &&
( Y1 >= ee.getAxisY() ) && ( Y1 <= Y2 ) )
{
isTrue =true;
}
if ( ( X1 >= ee.getAxisX() ) && ( X1 <= X2 ) &&
( Y1 >= ee.getAxisY() ) && ( Y1 <= Y2 ) )
{
isTrue =true;
}
//从坦克前进方向的上面判断是否有相撞
if ( ( et.getAxisY() < Y1 ) && ( Y1 < Y2 ) )
{
isTrue =true;
}
//如果相撞了才需要设置坦克的新方向。这一点需要注意;设置自己方向改变
if ( isTrue == true )
{
//this.setDierction(0);
}
}
}
break;
//我方坦克向右
case 1 :
/**
* 定义X1,Y1;用于界定坦克的另外三个点的坐标
*/
X1 = et.getAxisX() + 53;
Y1 = et.getAxisY() + 33;
for (int i = 0; i < getEnemyTankOfCount.size(); i++)
{
//取到的坦克元素可能是自己
EnemyTank ee = getEnemyTankOfCount.get(i);
//如果ee的方向是往上或者往下的
if ( (ee.getDierction() ==0) || (ee.getDierction() == 2))
{
X2 =ee.getAxisX() +33;
Y2 =ee.getAxisY() +53;
}
else
{
X2 = ee.getAxisX() + 53;
Y2 = ee.getAxisY() + 33;
}
/**
* 如果坦克ee不是自己,同时还活着
*/
if ((ee != et) && (ee.isLive() ==true) )
{
/**
* 根据 我方坦克的上面左右两个顶点和坦克相比较得出是否相撞,并且改变方向
*/
//待比较坦克方向是向上/向下/想左/向右的
//从坦克前进方向判断是否相撞
if ( ( X1 >= ee.getAxisX() ) && ( X1 <= X2 ) &&
( et.getAxisY() >= ee.getAxisY() ) && ( et.getAxisY() <= Y2 ) )
{
isTrue =true;
}
if ( ( X1 >= ee.getAxisX() ) && ( X1 <= X2 ) &&
( Y1 >= ee.getAxisY() ) && ( Y1 <= Y2 ) )
{
isTrue =true;
}
//从坦克前进方向的后面
if ( ( et.getAxisX() < X2 ) && ( X2 < X1 ) )
{
isTrue =true;
}
//如果相撞了才需要设置坦克的新方向。这一点需要注意;设置自己方向改变
if ( isTrue == true )
{
//this.setDierction(3);
}
}
}
break;
//我方坦克向左
case 3:
/**
* 定义X1,Y1;用于界定坦克的另外三个点的坐标
*/
X1 = et.getAxisX() + 53;
Y1 = et.getAxisY() + 33;
for (int i = 0; i < getEnemyTankOfCount.size(); i++)
{
//取到的坦克元素可能是自己
EnemyTank ee = getEnemyTankOfCount.get(i);
//如果ee的方向是往上或者往下的
if ( (ee.getDierction() ==0) || (ee.getDierction() == 2))
{
X2 =ee.getAxisX() +33;
Y2 =ee.getAxisY() +53;
}
else
{
X2 = ee.getAxisX() + 53;
Y2 = ee.getAxisY() + 33;
}
/**
* 如果坦克ee不是自己,同时还活着
*/
if ((ee != et) && (ee.isLive() ==true) )
{
/**
* 根据 我方坦克的上面左右两个顶点和坦克相比较得出是否相撞,并且改变方向
*/
//待比较坦克方向是向上/向下/想左/向右的
//坦克前进方向碰撞到了坦克
if ( ( et.getAxisX() >= ee.getAxisX() ) && ( et.getAxisX() <= X2 ) &&
( et.getAxisY() >= ee.getAxisY() ) && ( et.getAxisY() <= Y2 ) )
{
isTrue =true;
}
if ( ( et.getAxisX() >= ee.getAxisX() ) && ( et.getAxisX() <= X2 ) &&
( Y1 >= ee.getAxisY() ) && ( Y1 <= Y2 ) )
{
isTrue =true;
}
//在坦克后面碰到了坦克
if ( ( et.getAxisX() < ee.getAxisX() ) && ( ee.getAxisX() < X1 ) )
{
isTrue =true;
}
//如果相撞了才需要设置坦克的新方向。这一点需要注意;设置自己方向改变
if ( isTrue == true )
{
//this.setDierction(1);
}
}
}
break;
default:
break;
}
return isTrue;
}