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

发布于 2024-10-31 17:49:00 字数 671 浏览 1 评论 0原文

我正在学习如何在 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
    }  
}

这有效,但我的编译器标记了一个警告:在构造函数中启动新线程是危险的。这是为什么呢?

这个问题的第二部分是:如果我在一个线程(串行端口侦听线程)中运行一个循环,并且在第二个线程中键入退出命令,该怎么办?如何让第一个线程终止?谢谢。

I am learning how to use threads in Java. And I wrote a class that implements Runnable to run concurrently to another thread. The main thread handles listening to the serial port where as the second thread will handle sending data to that same port.

public class MyNewThread implements Runnable {
    Thread t;

    MyNewThread() {
        t = new Thread (this, "Data Thread");
        t.start();
    }

    public void run()  {
        // New Thread code here 
    }

There first thread starts the second like this:

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

This works but my complier flags a warning saying: It is dangerous to start a new thread in the constructor. Why is this?

The second part to this question is: how if I have a loop running in one thread (the serial port listen thread) and I type an exit command in my second thread. How do I get the first thread to terminate? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦太阳 2024-11-07 17:49:00

对于第一个问题:在传入 this 的构造函数中启动线程会转义 this。这意味着您实际上是在对象完全构造之前给出了对对象的引用。该线程将在构造函数完成之前启动。这可能会导致各种奇怪的行为。

对于第二个问题:在 Java 中没有可接受的方法来强制另一个线程停止,因此您将使用一个变量,线程将检查该变量以确定它是否应该停止。另一个线程将设置它以指示第一个线程将停止。该变量必须是易失性的或所有访问都是同步的,以确保正确发布。这是一些类似于您想要的代码。

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
         }
    }
}

无论想要创建和启动线程都会执行以下操作:

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

无论想要停止线程都会执行以下操作:

thread.stop();

To your first question: Starting a thread in a constructor passing in this escapes this. That means that you are actually giving out a reference to your object before it is fully constructed. The thread will start before your constructor finishes. This can result in all kinds of weird behaviors.

To your second question: There is no acceptable way to force another thread to stop in Java, so you would use a variable which the thread would check to know whether or not it should stop. The other thread would set it to indicate that the first thread would stop. The variable has to be volatile or all accesses synchronized to ensure proper publication. Here is some code which would be something like what you want.

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
         }
    }
}

Whatever wants to create and start the thread would do:

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

Whatever wants to stop the thread would do:

thread.stop();
嘿哥们儿 2024-11-07 17:49:00

让我们看一个基本示例:

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 被认为是转义构造函数。这意味着该对象可供引用,但可能无法创建在构造函数中构建的所有其字段。如果把这个提升到另一个层次,如果 b 是final,你会期望它可用,但并不能保证。这被称为部分构造对象,并且在 java 中是完全合法的。

Lets take a look at a basic example:

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
   }
}

In this instance the MyClass.this is said to escape the constructor. That means that the object is available to reference but all of its fields that are being built in the constructor may not be created. To take this to another level what if b was final You would expect it to be available but it is not ensured. This is known as a partially constructed objects and is perfectly legal in java.

岛歌少女 2024-11-07 17:49:00

关于第二个问题,
您可以使用 isAlive 方法检查第二个线程是否已终止,如果是,请使用 break 关键字关闭第一个线程的循环,然后如果没有必要,则将终止做

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;
 }

}  
}

about second question ,
you can check if second thread has been terminated or not by isAlive method and if yes use break keyword to turn off the looping for first thread then will be terminated if nothing has to do

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;
 }

}  
}
淡淡の花香 2024-11-07 17:49:00

这个问题的第二部分是:
如果我有一个循环在其中运行怎么办
thread(串口监听线程)
然后我在我的
第二个线程。我如何获得第一
线程要终止吗?

让它继续循环,直到达到一个条件。例如:

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

The second part to this question is:
how if I have a loop running in one
thread (the serial port listen thread)
and I type an exit command in my
second thread. How do I get the first
thread to terminate?

Have it keep looping until a condition has been reached. For example:

public void run() {
    while ( !inputConsole.getCommand().equals("exit") ) {
        //Do Something
        Thread.sleep(1000); //put thread to sleep for 1 second
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文