调用父函数的Java线程

时间:2015-04-25 21:27:57

标签: java

我正在制作一些用java编写的软件,它涉及一个单一的父母'调用在自己的线程中运行的许多类(节点)的类(扩展Thread)。

类将父类存储为变量。如果节点类从父类调用方法,每个节点是否存储父对象的副本,或者所有节点是否对同一对象起作用?如果所有节点都作用于同一个对象,那么被调用函数中的do语句是在节点的线程中运行还是在父类的线程中运行?

EX代码:

    class parent
    {
        ArrayList<node> nodes = new  ArrayList<node>();
       void createStartNodes()
       {
          for(int i =0; i < 36;++i)
          {
             nodes.put(i,new node(this));
             nodes.get(i).start();
          }
       }
       void callSomeFunc()
       {
           /* things */
       }
    }
class node extends Thread
{
   parent par;
   public node(parent p)
   {
      par=p;
   }
  @Override
  public void run()
  {
     par.callSomeFunc();
  } 
}

3 个答案:

答案 0 :(得分:5)

我觉得你很困惑。我只想在回答你的问题之前澄清这些问题:

  • 类不会“在线程中运行”,因为它不会“运行”。您可以运行方法,而不是类。 根据您调用它的位置,可以在不同的线程中执行类的方法。

  • 在扩展Thread课程时(请注意大写字母T),您应覆盖run()方法,而不是start()方法,否则多线程的东西不会发生。但是,您确实必须调用 start() ,在Thread类中定义,而后者将在创建的线程中调用您的run()方法,正如你所料。 [编辑:这一点在OP的编辑中显然得到了解决]

话虽如此,回到你的实际问题:

  

每个节点都存储父对象的副本或执行所有节点   对同一个对象采取行动?

每个java对象(读取非基本类型)只是一个引用,您不传递对象值。因此,所有节点都存储对同一对象的引用,因为在调用构造函数时,它们向同一对象提供了引用(this)。

  

调用函数中的do语句在节点的线程中运行   在父类的线程中?

在代码的当前状态中,您不会覆盖run()而是覆盖start(),因此您无论如何都没有多个线程。(由OP解决)

run()方法中执行的代码将在节点的线程中执行,即使从run() 调用其他方法也是如此。

旁注:这是因为您正确调用了node.start()。如果您直接调用node.run(),则会在您调用run()的帖子中执行。

答案 1 :(得分:1)

首先,你应该覆盖Thread类的start()方法,你应该调用它。并且类似地,你不应该调用Thread类的run()方法,你应该覆盖它。

所以当你打电话给你的父母&#34; run()方法中的类,它在新实例中起作用,而不是由您创建的所有其他线程共享。

编辑:你已经过去了#34;这个&#34;对于构造函数,它们将共享相同的对象。

答案 2 :(得分:1)

  

每个节点是存储父对象的副本还是所有节点都作用于同一对象?

它们每个都存储指向父对象的内存位置的指针。他们确实对同一个对象采取行动。

  

如果所有节点都作用于同一个对象,那么被调用函数中的do语句是在节点的线程中运行还是在父类的线程中运行?

它们在尝试修改父对象的节点的线程中运行。您可能希望确保在执行此操作时正确使用同步,例如使用synchronized块。否则,当存在对父对象的并发访问时,可能会出现不正确/不一致的行为。例如:

class Node extends Thread
{
    Parent par;

    public Node(Parent p)
    {
       par=p;
    }

    @Override
    public void run()    
    {
       synchronized(par) {
           par.callSomeFunc();
       }
    } 
}

synchronized块将为该线程提供对父对象的独占访问权。

此外,线程特定逻辑应该在run方法中,而不在start方法中。