【问题标题】:Calling a method of a class which extends Thread, from another class从另一个类调用扩展 Thread 的类的方法
【发布时间】:2016-06-07 05:53:31
【问题描述】:

我知道这是一个有点幼稚的问题,但我想了解 Java 中多线程背后的基本工作原理。考虑下面的代码,说A在主线程中执行,它开始执行另一个工作线程,在B类中定义。我想知道B.func1是否可以从A调用并运行B的方法,是否可以并行执行?

public class A {
    public static void main(String[] args) {
        B obj = new B();
        obj.start();
        obj.func1();
    }
}

public class B extends Thread {
    public B() {
        //constructor
    }
    public void run() {
        while(true) {
            //do somethings
        }
    }
    public void func1() {
        //do someotherthings
    }
}

【问题讨论】:

  • @HovercraftFullOfEels 共享字段应该正确同步,在某些情况下使它们易失性就足够了,但对于其他情况,这可能涉及其他同步机制
  • @HovercraftFullOfEels,IMO,您只会让菜鸟们误入歧途,告诉他们同步 方法。同步的唯一目的是保护数据。我们经常谈论需要同步一个方法,而我们真正的意思是我们需要同步一些由该方法独占访问的数据。但更常见的是,可以通过不止一种方法访问相同的数据。新手需要知道synchronized 不起作用,除非每一 位访问共享数据的代码在同一个对象 上都是synchronized
  • @jameslarge:你是对的。评论已删除,感谢您的澄清/更正。
  • 是否可以确定执行顺序? B 类的 run 方法后跟 B 类的 funct1 方法还是相反?

标签: java multithreading


【解决方案1】:

方法调用背后没有魔法。如果您从线程调用方法,它会在完全相同的线程中调用。所以由于obj.func1()是从main调用的,所以会在主线程中运行。它属于哪个类或它是否扩展 Thread 都没有关系。

新线程从执行run 开始。从 run 等调用的所有内容都将与 main 并行执行。

【讨论】:

  • 刚刚意识到您已经更正了有问题的源代码 :)
【解决方案2】:

您的代码存在多个问题。我已更正它们并添加了一条语句以在 func1() 中打印线程名称。

工作代码:

public class A {
    public static void main(String args[]){
        B obj = new B();
        obj.start();
        obj.func1();
    }
}

class B extends Thread{
    public B (){
        //constructor
    }
    public void run(){
        while(true){
            //do somethings
        }
    }
    public void func1 (){
        //do someotherthings
        System.out.println("Thread name="+Thread.currentThread().getName());
    }
}

输出:

Thread name=main

由于您直接从 main 方法 (A.java) 调用 func1() ,因此您将在输出中得到 Thread name = main

如果您添加相同的打印语句run() 方法,您将得到输出为:Thread name=Thread-0

【讨论】:

    【解决方案3】:

    了解线程Thread之间的区别很重要。

    线程 是您的代码的独立执行。通常,当我们谈论某种方法或其他方法如何工作时,我们会说“它测试变量 x,如果 x 小于零,它会调用 foobar 方法......”

    好的,但那句话中的“它”是什么? 不是方法。方法不任何事情。方法只是一个指令列表,例如某人留给室友执行的家务列表。这份清单并没有做家务,而是室友做的工作(或者我们可能希望如此)。

    “它”是一个线程。线程是操作系统中执行方法的实体(即,它们做家务)。

    另一方面,Thread 是一个 Java 对象,您的程序可以使用它来创建和管理新的线程。您的程序通过执行以下操作创建一个新的 Thread 对象:

    thread t = new Thread(...);
    

    [哎呀!看看我刚刚做了什么?不是您的程序 完成工作,而是您的程序的主线程,或者可能是您程序中的某个其他线程。这很容易忘记!]

    无论如何,它随后会通过调用t.start();

    创建新的线程

    一旦你明白了这一切,那么 Sergey Tachenov 的答案就很明显了:调用 Thread 对象的方法确实与调用任何其他类型对象的方法没有什么不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-03
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-18
      相关资源
      最近更新 更多