【问题标题】:Java: Start Thread (Alternative to starting in constructor)Java:启动线程(替代在构造函数中启动)
【发布时间】:2015-07-05 11:02:16
【问题描述】:

是否有另一种方法可以在创建对象时(调用构造函数时)启动线程。我知道你不能在构造函数中启动线程。但是,如果我在实现 Runnable 的类(类称为 Tasks)中有两个方法:run()、continuousRecv()。 run() 方法调用 ContinuousRecv() 函数。 ContinuousRecv() 做了一些事情。然后我在公共类 Tasks 中创建一个名为 startContRecv() 的私有类,并在构造函数调用中启动线程,就像这样

Thread t1 = new Thread(new Tasks());
t1.start();

我的代码:

import java.lang.Runnable;

public class Tasks implements Runnable {
    public Tasks() {
        startContinousReceive conRecv = new startContinousReceive();
    }

    public void continuiousReceive() {
        while (true) {
            //Code to executed
        }
    }

    public void run() {
        continuiousReceive();
    }

    //PRIVATE CLASS WHICH STARTS THREAD
    //INSTANCE OF PRIVATE CLASS IS MADE IN CONSTRUCTOR OF TASKS CLASS

    private class startContinousReceive {
        public startContinousReceive() {
            Thread t1 = new Thread(new Tasks());
            t1.start();
        }
    }
}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    您将获得一个无限循环的实例化 Tasks 对象,最终肯定会出现 OutOfMemoryError。您实例化 Tasks 的 object1,然后再实例化您的私有类,后者再次实例化 Tasks 的另一个 object2,然后循环重新开始。

    【讨论】:

    • 你知道在课堂上成功启动线程的方法吗?顺便说一句,无限循环不会执行任何消耗内存的任务,例如
    • public void continiousRecieve() { while (true) { String recv = sock.receivePacket(); if (recv != null) { internalRoomID = Integer.parseInt(recv.split("%")[3]); } } }
    • 你错过了我的意思,你进入了创建任务对象的无限循环。当然,这会在某些时候影响内存:)。
    • 通过从您的私有类构造函数调用Tasks的构造函数,它将再次调用您的私有类构造函数,该构造函数将再次调用Tasks构造函数。如果我认为这更好,它将永远不会结束对象构造,我认为您会更快地获得 StackOverflow :)
    • 我不明白,请给我演示代码
    【解决方案2】:

    实现你想要的最简单的方法:在创建任务时也用它启动一个线程是在Tasks类中定义一个工厂方法,并将Tasks构造函数设为私有。见下文:

    public static void createTask( ) {
        Tasks t = new tTasks();
        Thread t  = new Thread( t) ;
        t.start( );
    }
    

    并声明您的构造函数为私有的,以确保实例化 Tasks 的唯一方法是通过此工厂方法。否则你也不会启动线程。 另外,你应该删除你的内部私有类,在这种情况下是没用的。

    【讨论】:

      【解决方案3】:

      为什么?

      在构造函数中做大量工作是一种反模式

      特别是,它破坏了您对构造函数进行子类化的能力。

      所以不要尝试在构造函数中启动线程!

      为什么是代码

      new MyThread().start();
      

      不好?它非常易读:创建一个新线程并运行它。

      如果你愿意,你仍然可以将它包装在一个方法中:

      public void startNewThread() {
        new MyThread().start();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多