繁体   English   中英

创建和使用匿名 Runnable 类的最佳方式

[英]Best way of creating and using an anonymous Runnable class

我想为Runnable使用匿名类。 有两种方法,但我不知道他们是否做同样的事情:

方法一:直接使用Runnable再调用run()

new Runnable() {
    @Override
    public void run() {
    }
}.run();

方法二:创建一个匿名Runnable并粘贴到Thread ,使用start()方法而不是run()

new Thread(new Runnable() {
    @Override
    public void run() {
    }
}).start();

我认为方法二显然是正确的。 但是,我不知道它是否与方法一相同。 我们可以直接在Runnable上调用run()方法吗?

不,您通常不会直接在 Runnable 上调用run() ,因为您不会以这种方式获得后台线程。 如果你不想要并且需要一个后台线程,那么可以直接调用run() ,否则如果你想创建一个后台线程并在其中运行你的 Runnable,你必须创建一个新的 Thread 然后传入 Runnable进入其构造函数,并调用start()

此外,还有其他方法可以完成此任务,包括使用 Executors 和 ExecutorServices,您应该研究它的用途,因为它们比使用简单的 Thread 对象提供了更多的灵活性和功能。

此外,您还需要了解Future接口和FutureTasks类的使用,它们与 Runnables 类似,只有它们允许您在完成时返回结果。 如果您使用过 SwingWorker,那么您已经使用了 Future 接口而没有意识到它。

正如其他人所提到的,使用 Thread 类是正确的方法。 但是,您还应该考虑使用 Javas Executors框架来处理正在运行的线程。

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override 
    public void run() {
        // code in here
    }
});

当然,直接使用Thread就可以了。 但通常建议(或首选)使用该框架。 让 Java 为您处理细节。

Runnable接口必须在Thread内执行。 如果你想找到另一种方法来包装内联,在Thread一段代码,尝试:

Thread t = new Thread()
{
     public void run()
     {
        // put whatever code you want to run inside the thread here.
     }
};

t.start();

我想在这个讨论中添加一些东西(你已经得到了很好的答案)。
如果您的 Runnable 对象是无状态的,为了减少内存分配(这需要时间+消耗一些内存-考虑应用程序大量使用线程的情况)-请考虑使用一个静态字段来保存可运行对象。

private static Runnable runnable = new Runnable() { //Once again - do this only if this is a statelss object!
   public void run() {
   }
} 

//Use the runnable somewhere in the code

在方法一中,它将像实现和调用它的 Runnable 接口一样工作,但不会创建后台线程。 事实上,当我们调用 start 方法时,它会导致相应的线程开始执行,Java 虚拟机在内部调用该线程的 run 方法。 所以要启动一个线程,我们需要调用带有接口 Runnable 引用的 start 方法。 在方法一中,我们甚至不能调用带有 Runnable 接口引用的 start 方法,因为 Runnable 接口不支持 start() 方法。因此必须创建 Thread 类的对象来启动线程执行。

永远记住 Runnable 只是您想要或能够在线程中运行的代码。 匿名定义 Runnable 代码的一种方法是:

  Runnable codeToRunOnThread=new Runnable() {
      @Override
      public void run() {
      //code to run in a thread you want
      }
  };

然后你可以创建一个线程并将你创建的 Runnable 传递给这个新线程

  Thread myThread=new Thread(codeToRunOnThread);
  myThread.start();

调用 Thread 类的 start() 方法后,run() 方法内部的代码将在新创建的线程上运行。

您还可以在此处查看创建 Runnable 对象的不同方式

这可以通过 lambda 表达式完成:

Runnable myRunnable = () -> {
    //code you want to execute
};

第一种方法是错误的:它不会创建一个新线程,所以它没用。

这就像将代码放在可运行对象之外。

请注意,有两种方法可以在匿名类中定义的代码上启动新线程, 如 Thread 的 javadoc 中所述,但您的方法 1不在其中,而您的方法 2是您通常更喜欢的方法。

正如@Hovercraft 所提到的,如果您直接调用Runnable.run()方法,则根本不会创建Thread 这就像调用任何其他方法( System.out.println(...) ,...)。

当你传递一个Runnable对象给Thread构造函数中,设定target领域的Thread是你的对象:

this.target = target;

然后,当您在Thread上调用start()时,这会完成分叉新线程并调用Thread.run()方法的工作。 Thread.run()调用目标的run()方法:

public void run() {
    if (target != null) {
        target.run();
    }
}

因此,将Runnable传递给一个Thread ,然后调用start()是在单独的线程中在后台运行Runnable的方法。

你的方法1通常不能做任何有用的工作。 使用这种方法,如果你想得到简单的HelloWorld.java 程序的输出,即“Hello World”,它会类似于下面的无用代码,但它会打印“Hello World”。 所以你应该使用你的第二种方法。 无用代码:

class MyRunnable implements Runnable {

    public void run() { 
    System.out.println("Hello World");
    }

    public static void main(String[]arg){ 
    MyRunnable myRunnable = new NamedRunnable( );
    namedRunnable.run();
    } 
}

下面是一个简单的代码示例,说明如何正确创建匿名 Runnable 类并处理内存泄漏(Android 示例):

public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {

            MyRunnable myRunnable = new MyRunnable(this);
            myHandler.postDelayed(myRunnable, TimeUnits);
}

// Must be declared as a static class    
private static class MyRunnable implements Runnable {
        WeakReference<MainActivity> mActivity;
        // Creating weakreference
        MyRunnable(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void run() {
            MainActivity activity = mActivity.get();
            // Checking reference exist or not
            if (activity != null) {
                    //Do necessary tasks
                }
            }
        }
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM