我正在创建一个游戏,我需要在同一个方法中运行2个线程,但是,其中只有一个正在移动。 第一个线程以秒为单位计算,另一个用于处理游戏中的电源 (不,这不是弗雷迪的五夜)。 我的游戏已经有很多文件,我不认为显示它们都是个好主意,我只会显示启动两个线程的方法。
@Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getX() + ", " + e.getY());
if (e.getX() > game.panel.startbtnx
&& e.getX() < game.panel.startbtnx + 96
&& e.getY() > game.panel.getHeight() / 2
&& e.getY() < game.panel.getHeight() / 2 + 36) {
if (game.state == State.MENU) {
game.state = State.GAME;
Ingame.alerts.add(new Alert("-9999 Points!"));
Ingame.powerhandler.start();
Ingame.secondcounter.start();
}
}
}
正如你所看到的,我的“powerhandler”线程完美无缺 “secondcounter”线程不起作用,如果我切换它们的位置, 然后只有第二个计数器工作,而不是powerhandler。 我该怎么办?
编辑:这些是我的线程代码,我有更多的线程,但是现在我只使用这些2:class SecondCounterHandler implements Runnable {
public static int seconds = 0;
public Thread thread;
public void start() {
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (true) {
try {
Thread.sleep(1000);
seconds++;
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
和
class CityPowerHandler implements Runnable {
public int power = 100;
public Thread thread;
public void start() {
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
Thread.yield();
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (true) {
if (power > 0) {
power--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
Game.g.state = State.LOSE;
}
}
}
}
答案 0 :(得分:1)
正如您所看到的,我的“powerhandler”主题完美无缺
我们可以看到?看什么?您没有向我们展示任何输出或描述任何行为。
然而“secondcounter”线程不起作用,
你是什么意思“不起作用”?如果有效,它会怎么做? 做什么呢?
如果我切换[他们的]位置,那么只有第二个计数器工作,而不是动力处理程序。
这是什么意思,“改变他们的位置?”线程没有“地方”。你在谈论你开始它们的顺序吗?
这可能是一个问题:
public void run() {
...
while (true) {
if (power > 0) {
power--;
...
} else {
Game.g.state = State.LOSE;
}
}
}
一旦power
达到零(线程启动后大约10秒),该线程将永远循环,使用100%CPU来连续设置Game.g.state = State.LOSE
。
这可能不是你想要的。
答案 1 :(得分:1)
使用线程来做这样的事情并不是一个好主意。使用摆动Timer代替,它会使很多事情变得更容易和更安全。
线程安全
摆动计时器在事件发送线程上运行,这意味着您不必为了线程安全而同步事物。
如果您使用线程,例如,从另一个线程修改power
成员变量,事情可能会变得奇怪:
if (power > 0) {
power--;
....
此线程可能会在if
和power--
之间中断,如果另一个线程将power
设置为零,power
最终可能会-1
。
此类错误可能 非常 以后很难找到,因为这种错误很少发生。通常情况下,当您不调试,但将程序显示给其他人时。
<强> InterruptedException的强>
无需使用计时器处理InterruptedException
。
<强>性能强>
应该更好,不需要创建很多线程。
<强>简单强>
使用计时器可以使您的代码更具可读性,您可以像处理其他事件一样处理计时器事件。
答案 2 :(得分:0)
在方法运行开始时,为什么不尝试添加Thread.yield();
?
请参阅:http://www.tutorialspoint.com/java/lang/thread_yield.htm
在这种情况下,Thread会在继续之前让其他'等待'Thread执行。
编辑:尝试在while(true)循环中添加Thread.yield();
答案 3 :(得分:0)
我假设你以某种方式在gui(来自EDT线程)上使用这个值,并注意到它没有改变。如果这是问题,则代码中存在可见性问题,在不正确发布/同步的情况下跨不同线程访问变量。
public static int seconds = 0;
请使用java.util.concurrent.atomic包中的AtomicInteger。
public static AtomicInteger seconds = new AtomicInteger(0);
并使用
seconds.incrementAndGet();
而不是
seconds++;