Java 线程管理的对象未进入另一线程上的堆栈
跟进我之前发布的关于战斗模拟器的问题 这里的问题是:“生物”对象不会进入“战斗”类的堆栈 整个问题是几个更大的类,但我已经设法将问题缩小到以下代码Java 线程管理的对象未进入另一线程上的堆栈,java,multithreading,Java,Multithreading,跟进我之前发布的关于战斗模拟器的问题 这里的问题是:“生物”对象不会进入“战斗”类的堆栈 整个问题是几个更大的类,但我已经设法将问题缩小到以下代码 public class Combat implements Runnable { int Turn = 0; HashMap<Integer, Faction> Factions = new HashMap<Integer, Faction>(); Stack<Creature> stack; publi
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!");
}
公共类战斗实现可运行{
整圈=0;
HashMap派系=新HashMap();
堆叠;
public int get派系支持(){
int结果=0;
迭代器F=派系.值().迭代器();
while(F.hasNext()){
如果(F.next().getMemberCount()>0)
结果=结果+1;
}
返回结果;
}
public HashMap GetForeigs(int-派系ID)抛出No派系异常{
HashMap targetPool=新HashMap();
迭代器F=派系.值().迭代器();
如果(!(F.hasNext())
抛出新的nosexception();
派系;
while(F.hasNext()){
温度=F.next();
if(temp派系.get派系ID()!=派系ID)
targetPool.putAll(temporation.getMembers());
}
返回目标池;
}
私有int getMaxInit(){
int Max=0,temp=0;
迭代器I=派系.值().迭代器();
while(I.hasNext()){
temp=I.next().getMaxInit();
如果(温度>最大值)
最大值=温度;
}
返回最大值;
}
公共int getTurn(){
回程;
}
公共无效设置回合(整数回合){
转身=转身;
}
//TODO我无法让生物进入堆栈!:@
同步公共无效推送(生物C){
堆栈推送(C);
System.out.println(“生物”+C.getName()+“现在在堆栈上”);
如果(C.getInit()==this.getMaxInit())
这个。emptyStack();
通知();
}
//TODO现在必须处理堆栈:每个人都做他们想做的事情
public void emptyStack(){
生物C;
而(!(stack.isEmpty()){
C=stack.pop();
C.采取行动();
}
匝数=0;
}
已同步的公共void increaseTurn(){
这个。转身=转身+1;
System.out.println(“当前倡议分数为”+this.getTurn());
notifyAll();
试一试{
睡眠(100);
}捕捉(中断异常e){
回来
}
}
公开募捐{
while(this.getPalitySRunding()>1){
增加转动次数();
}
}
}
公共类生物扩展可观察工具可运行{
同步公开作废公告(){
试一试{
if(batch.getTurn()!=this.getInit())
等待();
战斗。推(这个);
}
捕捉(中断异常e){
回来
}
}
公共行动{
攻击(this.Target,this.leftHandWeapon);
if(this.Target.getCurrentHP()<0)
this.Target=null;
}
public void setTarget(){
整数targetID=-1;
HashMap目标池;
对象[]目标键;
试一试{
目标池=战斗。获取敌人(FID);
if(targetPool.isEmpty())
抛出新的EmptyTargetPoolException();
targetKeys=targetPool.keySet().toArray();
如果(targetKeys.length==0)
抛出新的EmptyTargetKeysArrayException();
if(this.Target==null){
做{
targetID=(整数)this.getRandom(targetKeys);/(整数)targetKeys[(整数)this.getRandom(targetKeys)];
}而(!(targetPool.keySet().包含((整数)targetID));
this.Target=targetPool.get(targetID);
}
}
捕获(清空目标池异常){
System.out.println(e.getMessage());
}
捕获(清空TargetKeysArrayException e){
System.out.println(e.getMessage());
}
捕获(例外e){
System.out.println(e.getMessage());
}
}
公开募捐{
//只要这个生物还活着,这种情况就会持续下去
而(此.currentHP>0){
试一试{
this.setInit();
这是setTarget();
这个。宣告();
}
捕获(例外e){
System.out.println(e.getMessage());
}
}
System.out.println(this.Name+“已被杀死!”);
}
}生物名称是否打印出来?如果是,则可能存在以下问题:
if (C.getInit() == this.getMaxInit())
this.emptyStack();
我不确定getInit()方法的作用,但是如果getMaxInit()也返回相同的值,那么每次调用push()时它都可以清空堆栈。这是我现在能看到的唯一可能发生的问题 GetInit()返回一个整数值,表示生物的主动性得分(例如,它的反应速度)。得分最高的生物应该最后进入堆叠并首先行动。看不出问题所在。我的建议是回去测试每一种方法,以确保它达到您认为的效果。这是缩小问题范围的唯一方法,否则我只能猜测。这些类根本不是线程安全的!