【问题标题】:Java, pass main class to child class, bad coding style?Java,将主类传递给子类,编码风格不好?
【发布时间】:2010-11-17 04:11:41
【问题描述】:

请多多包涵,因为我还在学习 Java。

下面的示例从名为 Parent 的类中读取数据,该类在 main 方法上创建自身的实例。然后它使该实例进行各种计算。

接下来它会启动一个名为 Child 的线程,将 Parent 实例作为对 Child 的引用。

Child 只是坐在那里监视事物,有时还会在 Parent 上启动公共方法。

它有效。问题是,这是不是很糟糕的风格?有没有更多的Java 思维方式来做这种工作?

public class Parent {

    // main function that fires up the program
    public static void main() {

        // creates an instance of himself
        // and fires go that does all sorts of fuzzy calculus
        Parent parent = new Parent();
        parent.go();

        // creates a new thread of child and starts it
        Child child = new Child(parent);
        child.start();
    }

    private void go() {
        // all sort of initializations
    }

    public void getDataFromChild(int data) {
        // will get data from running child thread
    }
}



public class Child extends Thread {
    private Parent parent;

    // child constructor grabs Parent instance into "o"
    public Child(Parent o) {
        parent = o;
    }

    // this class main loop
    public void run() {
        while(1==1) {
            doSomething();
            try {
                sleep(1000);
            }
            catch(Exception e) { }
        }
    }

    private void doSomething() {
        parent.getDataFromChild(1);
    }

}

谢谢。

【问题讨论】:

  • 应该有办法终止子线程(但也许无限的while循环只是一个简化的例子)。

标签: java implementation


【解决方案1】:

子类化线程被认为是不好的风格。最好实现 Runnable,然后将 runnable 交给线程(嗯……非常类似于您的 Parent/Child 移交!)。

Runnable r = new Child(parent);
new Thread(r).start();

否则您的 Child.java 代码对我来说看起来不错。

要实现 Runnable,你只需要提供一个 run() 方法:

public class Child implements Runnable {
  private Parent parent;

  public Child(Parent parent) { this.parent = parent; }

  public void run() {
    // what the thread does goes in here...
  }

【讨论】:

  • 感谢您的回答。我一直在尝试几种不同的实现并阅读了很多。你的回答真的很有帮助。谢谢!
【解决方案2】:

问题是,这种风格很差吗?有没有更多的 Java 思维方式来做这种工作?

向“子”对象传递对其“父”的引用既不是好的样式也不是坏的样式。这只是编程。

在一个真实的应用程序中(而不是你的高度人工的例子),你可以判断这是否是好的设计

【讨论】:

  • 喜欢你的“这只是编程评论”。几周后,从不同的角度看待它是完全正确的。谢谢!
【解决方案3】:

除了Julius Davies'的回答,我对这样的代码还有一个顾虑:

    Child child = new Child(parent);

也就是说,为什么孩子在自己的线程中,孩子要对父母做什么?

如果父线程真的像看起来那样微不足道,那么子线程似乎就没有必要了。另一方面,如果父线程在子线程启动后做更多的工作,那么您就会遇到需要处理的同步问题。而您必须与他们打交道。墨菲定律说,任何可能发生的线程问题,发生。 (推论:即使您是墨菲定律方面的专家,可能的线程问题也比您意识到的要多。)

编辑:好的,子线程调用parent.getDataFromChild。该方法对数据有什么作用? (它是否对也从主线程访问的对象进行任何更改?)由于它是从子线程调用的,因此您需要检查父类和子类是否存在可能的竞争条件。

【讨论】:

    【解决方案4】:

    除了Child 类应该实现Runnable 之外,我认为这没有任何问题。只要您记录ParentChild 之间的关系,它看起来就很好。

    【讨论】:

      【解决方案5】:

      如果 Child 在其他地方被引用,您需要覆盖父级上的 finalize 方法以清理它们。否则,我似乎完全可以接受。

      【讨论】:

        【解决方案6】:

        关于你写的内容,最好让 Child 可以在线程中运行

        http://www.javabeginner.com/learn-java/java-threads-tutorial

        然后关于这是否是一个好方法的问题,答案是:这取决于你想做什么LOL

        你可以研究几件事:

        • 捕捉各种异常,如

        中断异常

        • 读取同步文件以防止同时访问/修改。

        • 您可以检查观察者类/设计模式来控制线程何时唤醒以进行测试,而不是睡眠

        最后,我想向您介绍用 Java 线程化您的应用程序的美妙世界:D

        编辑:正如 Dave L 所指出的,你需要注意清理你引用的内容,否则你最终会在你的程序中遇到僵尸 ^^

        【讨论】:

          【解决方案7】:

          我从你的代码中读到的是一个糟糕的循环依赖。

          你可以使用接口来移除依赖。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-09-23
            • 1970-01-01
            • 1970-01-01
            • 2013-07-08
            • 1970-01-01
            • 1970-01-01
            • 2022-01-22
            相关资源
            最近更新 更多