为什么不在构造函数中启动线程? 如何终止?

我正在学习如何在Java中使用线程。 而且我写了一个实现Runnable并行运行到另一个线程的类。 主线程处理侦听串口,第二个线程将处理发送数据到同一端口。

public class MyNewThread implements Runnable { Thread t; MyNewThread() { t = new Thread (this, "Data Thread"); t.start(); } public void run() { // New Thread code here } 

有第一个线程启动第二个像这样:

 public class Main { public static void main(String[] args) throws Exception{ new MyNewThread(); // First thread code there } } 

这工作,但我的编译器标志警告说:在构造函数中启动一个新的线程是危险的。 为什么是这样?

这个问题的第二部分是:如果我有一个循环运行在一个线程(串口侦听线程),我在我的第二个线程中键入一个退出命令。 我如何获得第一个线程终止? 谢谢。

对你的第一个问题:在构造函数中传递一个线程在this转义。 这意味着,在完全构build之前,实际上是在发布对象的引用。 线程将在您的构造函数完成之前启动。 这可能会导致各种怪异的行为。

对于第二个问题:没有可接受的方法来强制另一个线程停止在Java中,所以你会使用一个variables,线程会检查它是否应该停止。 另一个线程将它设置为表示第一个线程将停止。 该variables必须是易失性的或所有访问同步,以确保正确的发布。 这里是一些代码,就像你想要的东西。

 public class MyNewThread implements Runnable { private final Thread t; private volatile boolean shouldStop = false; MyNewThread() { t = new Thread (this, "Data Thread"); } public void start() { t.start(); } public void stop() { shouldStop = true; } public void run() { while(!shouldStop) { // do stuff } } } 

不pipe想要创build和启动线程,都可以这样做:

 MyNewThread thread = new MyNewThread(); thread.start(); 

无论什么想停止线程会做:

 thread.stop(); 

让我们看一个基本的例子:

 class MyClass implements Runnable{ int a = 0; String b = null; public MyClass(){ new Thread(this).start(); b = "Foo"; } public void run(){ a = b.length(); //can throw NullPointerException } } 

在这种情况下, MyClass.this被认为是逃避构造函数。 这意味着该对象可供引用,但是可能不会创build构造函数中构build的所有字段。 把这个带到另一个层次如果b是final你会期望它是可用的,但不能保证。 这被称为部分构造的对象,在java中是完全合法的。

关于第二个问题,你可以通过isAlive方法检查第二个线程是否被终止,如果是,使用break关键字closures第一个线程的循环,那么如果什么都不需要

 public class MyNewThread implements Runnable { Thread t; MyNewThread() { t = new Thread (this, "Data Thread"); t.start(); } public void run() { reading code ................ // New Thread code here } 

 public class Main { public static void main(String[] args) throws Exception{ MyNewThread thread = new MyNewThread(); while(true) { listening code ................... if(!thread.t.isAlive()) break; } } } 

这个问题的第二部分是:如果我有一个循环运行在一个线程(串口侦听线程),我在我的第二个线程中键入一个退出命令。 我如何获得第一个线程终止?

让它保持循环,直到达到条件。 例如:

 public void run() { while ( !inputConsole.getCommand().equals("exit") ) { //Do Something Thread.sleep(1000); //put thread to sleep for 1 second } }