【问题标题】:Thread object in event method: use class member or create local object?事件方法中的线程对象:使用类成员还是创建本地对象?
【发布时间】:2012-04-13 04:03:09
【问题描述】:

我有一个带有事件方法的类,它经常被调用。假设方法名称是:onClicked。在方法内部,我会创建一个线程来做一些事情。

首先,我尝试在事件方法中创建一个线程对象。代码是这样的:

public class MyService {

    //Event method
    public void onClick() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                // do some stuff here
            }
        }).start();
    }
}

但是由于经常会调用 onClick,我担心每次调用事件方法时创建的新线程对象是否会造成内存空间或性能问题?

或者,我可以像这样创建一个类成员线程解决方案:

public class MyService {
    private Thread myThread;

    //Event method
    public void onClick() {
        myThread = new Thread(new Runnable() {

            @Override
            public void run() {
                  // do some stuff here
            }
        });
        myThread.start();
    }
}

那么哪个代码更好?第一还是第二?还是有其他更好的解决方案?

【问题讨论】:

  • 不是一个真正的问题。您必须每次都创建一个新线程,您别无选择,因此没有“更好”的选择。

标签: java android memory object


【解决方案1】:

如果不重新初始化每个OnClick() 上的线程,您将无法使用第二个代码。这是因为一旦线程完成运行,它就“死了”。因此,对start() 的后续调用将失败并导致IllegalThreadStateException

最好使用第一个代码,因为 GC 完成后会删除线程。

【讨论】:

  • 对不起,我的第二个代码出错了。我已经更新了它。那么使用成员线程变量的第二个代码在内存节省或性能方面仍然与第一个代码没有任何区别?
  • 正确,因为无论哪种方式都必须调用 Thread() 构造函数。
【解决方案2】:

我认为这两种解决方案都是相同的,因为它们每次都在创建一个新线程onclick。第二个甚至会遇到创建一个新线程并将其分配给全局变量myThread的情况,在它调用start之前,另一个onclick事件进来并重新分配全局变量,而前一个永远不会启动. 我建议你看看

ThreadPoolExecutor

控制这里允许的线程数,避免资源耗尽。

【讨论】:

    【解决方案3】:

    创建并初始化ExecutorService 然后点击你可以创建你自己的实现Runnable接口的类的任何实例。它的要点是通过指定池的数量(大小)来避免创建过多的线程(ExecutorService:修复线程池)。这是一个更好的方法。

    就像我说的,你也可以做一些小的重构,创建自己的类事件并实现Runnable,重点是定义构造函数,字段也可以是一些额外的方法。

    【讨论】:

    • 你给出的第一个解决方案和evanwong的一样,对吧?对于第二个(创建可运行的类事件),它会提高性能吗?
    • 这里不是性能问题,更多的是设计代码。但是您仍然可以使用池中的线程数。但请记住,我们正在处理移动系统(电池寿命/性能)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多