当前位置: 首页 > 面试题库 >

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

卢晟
2023-03-14
问题内容

我写了一个实现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 escapes 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();


 类似资料:
  • 当一个对象被创建时(当构造函数被调用时),有没有一种替代的方法来启动一个线程。我知道你不能在构造函数中启动线程。但是如果我在类中有两个方法(类被称为任务),它们实现了Runnable: run(),连续的Recv()。run()方法调用连续的Recv()函数。连续的Recv()做一些事情。然后我在公共类中创建了一个私有类,名为start ContRecv(),在构造函数调用中启动线程,就像这样 我

  • 问题内容: 我是Java编程语言的初学者,最近我研究了 构造函数 不能在Java中继承,有人可以解释 为什么 吗? 问题答案: 简而言之,构造函数不能被继承,因为在子类中它具有​​不同的名称(子类的名称)。 您只能执行以下操作: 相反,方法是使用“相同名称”继承的,可以使用。 理由如下:继承构造函数没有多大意义,因为类A的构造函数意味着创建类型A的对象,而类B的构造函数意味着创建类B的对象。 不过

  • 问题内容: 我正在处理一个扩展的类。 这不是我的代码,它在开始构造GUI之前先进行调用。我想知道为什么要这样做,因为我一直只访问超类的方法而不必调用; 问题答案: 对于具有父级的所有类(这是Java中每个用户定义的类),都有一个不带参数的隐式调用,因此通常不需要显式调用。但是,如果父级的构造函数接受参数,并且你希望指定它们,则可以使用参数调用。此外,如果父级的构造函数接受参数,并且没有默认的无参数

  • 问题内容: 在Java的构造函数中,如果要调用另一个构造函数(或超级构造函数),则它必须是该构造函数的第一行。我认为这是因为不允许您在其他构造函数运行之前修改任何实例变量。但是,为什么不能在构造函数委派之前使用语句,以便计算另一个函数的复杂值?我想不出任何正当的理由,在一些实际案例中,我编写了一些丑陋的代码来解决此限制。 所以我只是想知道: 有此限制的充分理由吗? 有没有计划在将来的Java版本中

  • 问题内容: 我对此代码有疑问:https : //github.com/reactjs/redux/blob/master/examples/async/containers/App.js 特别: 我猜这是一个两部分的问题。 为什么我需要将句柄更改设置为类的实例,我不能只对handleChange使用静态函数并直接在类中调用它 ? 我不知道这是怎么回事: 谢谢 问题答案: 以相反的顺序回答… 返回

  • 考虑这个程序本质上创建了<代码> STD::线程< /代码>,调用函数<代码>函数()/代码>以<代码> ARG作为参数: 我的输出是 据我所知,在线程对象中内部复制,然后作为右值(移动)传递给。所以,我期待一个副本建设和一个移动建设。 为什么会有第二步建设?