将运行的线程对象添加到arraylist中

时间:2013-04-24 12:55:18

标签: java multithreading arraylist

我正在使用java创建一个小坦克游戏。在那个游戏中,lifepacks和硬币堆是在游戏网格上随机的随机位置生成的。他们都有有限的生命期终身过期后他们将从现场消失。当它们在网格上可见时,任何坦克都可以在消失前获得它们。我想在 ArrayList 中保留lifepack对象和coinpile对象的列表,以便通过游戏AI算法访问它们。我希望使用简单的java知识实现以下概念。

以下是我的LifePack类.CoinPile类的行为方式类似:

public class LifePack extends Thread{
    public int healthBonus;
    public int lifetime;
    public String type;
    public Point location;
    public boolean visible;

    public LifePack(int x,int y,int lifetime){
        location=new Point(x, y);
        this.lifetime=lifetime;
        this.type="health_pack";
        this.visible=true;
        this.start();

    }

    public void run(){
        while(true){

            if(this.lifetime>0){
                try{
                    Thread.sleep(1);
                    if(lifetime%1000==0){
                        System.out.println("Life pack "+this.getId()+" will be disappeared in "+this.lifetime/1000+" s");
                    }
                    this.lifetime--;
                }
                catch(Exception ex){
                    ex.printStackTrace();
                }
            }
            else{
                this.visible=false;
                this.interrupt();
                break;
            }
        }
        System.out.println("Life pack visibility = "+this.visible);
    }


}

我想将新创建的LifePack对象添加到arraylist中,如下所示:

public ArrayList<LifePack> lifePacks;
lifePacks = new ArrayList<LifePack>();

lifePacks.add(new LifePack(x, y, lifeTime));

每次创建一个新的lifepack时,我都会将lifepack对象添加到上面的arraylist中。一旦lifepack的生命周期到期,我想将上面类中的'可见'布尔变量设置为' false ',以便我可以将该变量用于其他目的。< / p>

但我没有得到我想要的输出。我可以像上面一样将正在运行的线程对象添加到arraylist中并保持线程状态运行,还是必须移动到其他实现?如果有解决方案,请有人帮我解决这个问题。

谢谢。

3 个答案:

答案 0 :(得分:0)

我同意dirkk的说法,你会开出太多线程。但要回答你的问题,你应该考虑使用AtomicBoolean进行可见。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

答案 1 :(得分:0)

从我看到,一个Thread检查列表中的某些条目是否为false,其他一些线程将设置为false,这需要是线程安全的

您可以通过在更新操作期间同步列表本身来实现这一点

  synchronized(list){
       //update the needed entry to false
  }

答案 2 :(得分:0)

正如已经指出的那样,创建线程是一个坏主意。特别是,一旦您的应用程序达到了存在很多lifepack的程度。另请注意,在构造函数中启动线程是非常糟糕的做法。如果你想使用普通线程,建议实现runnable(java.lang.Runnable)。

但是,一般情况下,我强烈建议您使用java.util.concurrent包中提供的Java并发抽象:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html使用ExecutorService运行callables(java.util.concurrent.Callable)允许你可以很容易地改变线程数。

我还会质疑你将所有lifepack存储在同一个集合中并为每个lifepack分配一个状态(visiblity)的想法。自发地,我可以想到以下场景:一旦游戏运行了一段时间,你将最终获得大量的救生包,其中大部分都不再使用了。因此,您可能需要考虑为lifepack可以使用的不同状态设置不同的集合。这也可以使丢弃对象变得非常容易(不需要遍历集合)。假设这些集合将被多个线程访问,您希望它们是线程安全的。为此,您还可以在java.util.concurrent包中找到各种类型的集合。