【问题标题】:Objects created in custom Thread run on main Thread在自定义线程中创建的对象在主线程上运行
【发布时间】:2014-07-30 21:15:38
【问题描述】:

在 Android 上,我有一个扩展 Thread 的类 MyThread。在 MyThread 中,我声明了一些对象并在 run() 方法中初始化它们。对象是具有自己的构造函数的自定义类的实例。其中一些触发另一个后台线程并接受也在 MyThread 的 run() 方法内部初始化的侦听器对象。我的问题是,这些监听器是在主线程而不是 MyThread 上执行的。

所以我的问题是:在什么线程上执行的自定义对象的方法是在自定义线程上实例化的?

【问题讨论】:

  • 可能在您提出的问题的末尾找不到您寻求的答案。

标签: java android multithreading


【解决方案1】:

在哪个线程上创建对象并不重要,重要的是从哪个线程调用对象上的方法。

例如:

class MyThread extends Thread {

    public MyObject myObject;

    @Override
    public void run() {
        myObject = new MyObject();

        /* Do stuff */
    }

}

使用这个类:

MyThread myThread = new MyThread();
myThread.start();
myThread.myObject.someMethod();

这里,someMethod 调用在主线程上完成

【讨论】:

  • 我会改写“使用这个线程” - 您的意思是在所述线程上执行三行代码,还是在描述所述线程的用法,这是模棱两可的。 -- +1 编辑
  • 我不明白为什么,例如Android 的 util.Log.d() 是在 myThread 上自动执行,同时调用 myObject.someMethod() (都在 run() 中调用)在主线程上执行?
【解决方案2】:

无论它们在哪个线程上实例化,对象(以及您的侦听器)都可以从任何引用它们的线程访问(无论这样做是否安全另一个问题也是如此)。

对象不存在于任何线程上 - 当您从线程 A 调用对象上的方法时,该方法中的代码将在线程 A 上运行,而与创建对象的线程无关。

【讨论】:

    【解决方案3】:

    当一个程序启动时,它是派对前的一个空房间。然后爱丽丝带着她的手提袋进来,开始收拾东西。过了一段时间,爱丽丝给鲍勃打电话,后来鲍勃来厨房帮爱丽丝。爱丽丝和鲍勃准备了一些糖果,过了一会儿,史蒂夫和莎拉拿着啤酒和薯条敲门。

    Alice、Bob、Steve 和 Sarah 是线程。爱丽丝是主线,因为她组织了聚会。糖果、啤酒和薯条是对象。请注意,史蒂夫带来了薯片,但爱丽丝也可以吃它们!莎拉负责啤酒,但其他人当然可以喝。谁(哪个线程)将什么(创建的对象)带到聚会上并不重要:内存在线程之间共享。

    现在,让我们来看看您的 Alice 是如何工作的。 Android 应用的主线程是一个事件循环,可以看作:

    while (running) {
      if (input != null) dispatch(input);
      sleepForSomeTime();
    }
    

    dispatch() 的调用最终将到达您的侦听器代码,因此它在处理触摸事件的同一线程上执行。谁创建了对象,谁注册了监听器等等都没有关系。

    我认为您的应用程序并非如此,但实际上可能需要在后台线程池中处理事件。这是通过给你的线程一个要完成的任务队列,并让你的事件驱动代码更新该队列来实现的(或者你可以使用java.util.concurrent中的执行器框架)

    请注意,您不应该在构造函数中启动线程,因为

    1. 有些对象在完全构造之前可能会被看到(如果您使用内部类或匿名类)
    2. 构造函数的目的是初始化字段。后台线程的创建应该由新建对象的用户来处理

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 2016-04-17
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多