![](/img/trans.png)
[英]Main not waiting for threads even after using Thread.join() in Java
[英]Main thread keeps waiting on new threads
我正在尝试为我的项目编写一些“游戏引擎”,并且遇到线程问题。 当我在主流程中创建线程(LoadThread)时,它一直等到Run();。 在LoadThread中结束。
//loading thread
public class LoadThread implements Runnable{
private boolean running = false;
private Thread loader = null;
public LoadThread(/*init data structures*/){
loader = new Thread(this);
}
public void start(){
running = true;
run();
}
synchronized public void run() {
System.out.println(" loading started ");
while(running){
//do some loading, when done, running = false
}
System.out.println(" loading done ");
}
}
//holds data, starts loading
public class SourceGod {
private LoadThread img_loader;
public void startLoading(){
img_loader = new LoadThread(/* some data structures */);
img_loader.start();
}
}
//runs the game
public class Game extends GameThread implements ActionListener{
private SourceGod sources;
public Game(Window full_screen){
sources = new SourceGod(/* some data structures */);
System.out.println("before");
sources.startLoading();
System.out.println("after");
}
}
//own thread to refresh
abstract public class GameThread extends JPanel implements Runnable{
//anything from there is not called before "after"
}
产量
before
loading started
//some loaded data report, takes about 2-3s
loading done
after
任何帮助将不胜感激。 (更多代码http://paste.pocoo.org/show/orCfn9a8yOeEQHiUrgjG/ )谢谢,Vojtěch
您的问题是您在构造函数中创建了Thread
对象,但是当您调用start()
您不是在启动线程,而是在同一线程中运行run()
方法。 扩展 Thread
与实现 Runnable
似乎有些混乱。
我认为您应该做的是:
// this should be of type Thread not LoadThread
private Thread img_loader;
...
// don't create the loader thread inside of LoadThread
img_loader = new Thread(new LoadThread(/* some data structures */));
img_loader.start();
LoadThread
是线程将要执行的Runnable
类型的类。 使用您当前的代码,调用时:
img_loader.start();
它实际上并不是在启动新线程,而只是调用LoadThread.start()
方法,该方法在同一线程中调用run()
:
public void start(){
running = true;
run();
}
编辑:
通过仔细查看提供的链接中的已发布代码,您正在LoadThread
构造函数内部创建Thread
对象。 这不是一个好的模式:
public LoadThread(/*init data structures*/) {
// not recommended IMO
loader = new Thread(this);
}
同样,当您调用LoadThread.start()
您不是在启动线程,而是在同一线程中调用run()
。 我会改用new Thread(new LoadThread())
模式。 如果您被困在将Thread
包装在LoadThread
内 ,则应将LoadThread.start()
更改为:
// this should be removed, you want to call Thread.start() instead
public void start(){
running = true;
// this will start the internal thread which will call run()
loader.start();
}
顺便说一句,如果要在另一个线程中将running
设置为false,则应将其标记为volatile
。
使用Runnable接口的方式存在一些问题:
这是您应该采取的措施:
//loading thread
public class LoadThread implements Runnable{
/** Wether or not the thread is running. */
private boolean running = false;
/** Wrapper thread. */
private Thread loader = null;
public LoadThread(/*init data structures*/){
loader = new Thread(this);
}
public void start(){
running = true;
loader.start();
}
@Override
public void run() {
System.out.println(" loading started ");
while(running){
//do some loading, when done, running = false
}
System.out.println(" loading done ");
running = false;
}
}
如您所见,如果要使用start方法,只需调用包装器线程start方法。
另外,如果您确实需要调用start,请考虑不使用可运行的方法,而是直接使用线程:
//loading thread2
public class LoadThread extends Thread{
/** Wether or not the thread is running. */
private boolean running = false;
@Override
public void run() {
running = true;
System.out.println(" loading started ");
while(running){
//do some loading, when done, running = false
}
System.out.println(" loading done ");
running = false;
}
}
那要简单得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.