线程管理的对象没有进入另一个线程的堆栈

时间:2011-06-24 15:23:34

标签: java multithreading

关于我发布的关于战斗模拟器的上一个问题的后续跟踪。

问题在于:'生物'对象不会进入'战斗'类的堆栈。

整个事情是几个更大的类,但我设法将问题缩小到以下代码。

public class Combat implements Runnable {
int Turn = 0;
HashMap<Integer, Faction> Factions = new HashMap<Integer, Faction>();   
Stack<Creature> stack;

public int getFactionsStanding() {
    int Result = 0;

    Iterator<Faction> F = Factions.values().iterator();

    while(F.hasNext()) {
        if (F.next().getMemberCount() > 0)
            Result = Result + 1;
    }

    return Result;
}

public HashMap<Integer, Creature> getEnemies(int factionID) throws NoFactionsException {
    HashMap<Integer, Creature> targetPool = new HashMap<Integer, Creature>();

    Iterator<Faction> F = Factions.values().iterator();

    if (!(F.hasNext()))
        throw new NoFactionsException();

    Faction tempFaction;

    while (F.hasNext()){
        tempFaction = F.next();

        if (tempFaction.getfactionID() != factionID) 

            targetPool.putAll(tempFaction.getMembers());                
    }

    return targetPool;
}

private int getMaxInit(){
    int Max = 0, temp = 0;
    Iterator<Faction> I = Factions.values().iterator();

    while(I.hasNext()){
        temp = I.next().getMaxInit();
        if (temp > Max)
            Max = temp;             
    }           

    return Max;
}

public int getTurn() {
    return Turn;
}

public void setTurn(int turn) {
    Turn = turn;
}

// TODO I can't get creatures to enter the stack! :@
synchronized public void push(Creature C){
    stack.push(C);

    System.out.println("Creature " + C.getName() + " is now on the stack");

    if (C.getInit() == this.getMaxInit())
        this.emptyStack();

    notify();
}

// TODO The stack must be processed now: everyone does what they intended to do
public void emptyStack(){
    Creature C;

    while (!(stack.isEmpty())){
        C = stack.pop();

        C.takeAction();
    }

    Turn = 0;       
}

synchronized public void increaseTurn(){
    this.Turn = Turn + 1;

    System.out.println("Current initiative score is " + this.getTurn());

    notifyAll();

    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        return;
    }

}


    public void run(){
    while(this.getFactionsStanding() > 1){
        increaseTurn();
    }
}
}

public class Creature extends Observable implements Runnable {

        synchronized public void declareAction(){
    try{
        if (Combat.getTurn() != this.getInit())
            wait();                 

        Combat.push(this);
    }
    catch (InterruptedException e){
        return;
    }
}

public void takeAction(){
    Attack(this.Target, this.leftHandWeapon);

    if (this.Target.getCurrentHP() < 0)
        this.Target = null;
}

public void setTarget() {
    Integer targetID = -1;
    HashMap<Integer, Creature> targetPool;
    Object[] targetKeys;

    try{
        targetPool = Combat.getEnemies(FID);

        if (targetPool.isEmpty())
            throw new EmptyTargetPoolException();

        targetKeys = targetPool.keySet().toArray();

        if (targetKeys.length == 0)
            throw new EmptyTargetKeysArrayException();

        if (this.Target == null) {
            do{
                targetID = (Integer) this.getRandom(targetKeys); //(Integer)targetKeys[(Integer) this.getRandom(targetKeys)]; 
            } while (!(targetPool.keySet().contains((Integer)targetID)));

            this.Target = targetPool.get(targetID);
        }
    }
    catch (EmptyTargetPoolException e) {
        System.out.println(e.getMessage());
    }
    catch (EmptyTargetKeysArrayException e) {
        System.out.println(e.getMessage());
    }
    catch (Exception e) {
        System.out.println(e.getMessage());
    }

}

public void run() {
    // This will go on and on as long as this creature is alive
    while (this.currentHP > 0) {
        try {
            this.setInit();

            this.setTarget();

            this.declareAction();                       
        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }
    }       

    System.out.println(this.Name + " was killed!");     
}

}

1 个答案:

答案 0 :(得分:0)

生物名称是否打印出来?如果是这样,可能会出现问题:

if (C.getInit() == this.getMaxInit())
    this.emptyStack();

我不确定getInit()方法的作用但是如果getMaxInit()也返回相同的值,那么每次调用push()时它都可以清空堆栈。这是我现在唯一可以看到的问题。