Runnable Interface和Lambda,这是正确的方法之一吗?

时间:2017-03-18 03:51:17

标签: java lambda

class RunnerL implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 10; i++) {
            System.out.println("demo3-Hello: " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Then, in main function:

        Thread t1 = new Thread ( () -> new RunnerL ().run() );
        Thread t2 = new Thread ( () -> new RunnerL ().run() );

        t1.start();
        t2.start();

此代码有效。但这是正确的方法之一吗?

另外,为什么以下不起作用?

Runnable task3 = () -> new RunnerL ();
new Thread (task3).start();

如果我将其更改为Runnable task3 = () -> new RunnerL ().run()Runnable task3 = new RunnerL(),则可行,为什么?

4 个答案:

答案 0 :(得分:1)

因为以下代码仅创建RunnerL实例,但run()的{​​{1}}方法并未真正运行它(不执行run方法)。线程在Runnable实例上调用run()(因此只调用lambda):

Runnable

虽然以下内容创建了 Runnable task3 = () -> new RunnerL (); 实例,并且在启动Thread时,它会直接在该实例上调用RunnerL方法:

run()

以上实际上是最好的选择,另一个不必要的工作将 Runnable task = new RunnerL(); 包装到另一个Runnable

答案 1 :(得分:1)

Lambda表达式在功能接口内提供方法的实现(定义)(仅包含单个抽象方法)。所以在这里,您需要了解您实际上是为run()接口的抽象Runnable方法提供实现。

为了更好地理解这个概念,只需将构造函数添加到RunnerL,如下所示,以便您可以注意到实际发生的事情:

class RunnerL implements Runnable {

    public RunnerL() {
        System.out.println(" constructor called ");
    }

    //Add your run() method here
}
  

为什么以下不起作用?   Runnable task3 =() - &gt; new RunnerL();   新线程(task3).start();

此Lambda表达式(即Runnable接口的run()方法的实现)只是为RunnerL&amp;创建对象。调用上面的构造函数(即打印语句'构造函数')。

  

如果我将其更改为Runnable task3 =() - &gt;新的RunnerL()。run(),它有效,为什么?

这个Lambda表达式创建了对象,通过打印'构造函数'来调用构造函数。然后调用您的run()方法。

答案 2 :(得分:0)

要使用Runnable接口创建和启动线程,您必须执行以下操作:

1)创建一个实现Runnable的类。

class RunnerL implements Runnable {}

2)在Runnable类中提供run方法。

 public void run() {
        // TODO Auto-generated method stub

        }

3)创建Thread类的实例,并将Runnable对象作为参数传递给它的构造函数。

创建了一个可以运行Runnable类的Thread对象。

RunnableClass rc = new RunnableClass();
Thread t = new Thread(rc);

4)调用Thread对象的start方法。

调用Runnable对象的run方法并在单独的线程中执行。

 t.start();

Runnable task3 =() - &gt; new RunnerL();

**This is not running your runnable class.Just creating an instance.**

答案 3 :(得分:0)

在Java8中,您实际上并不需要在班级中实施Runnable。如果方法具有正确的签名,Java将接受该方法作为Runnable。所以,例如:

class CountToTen {
    public void count() {
        IntStream.rangeClosed(1, 10).forEach(System.out::println);
    }
}

CountToTen counter = new CountToTen();
Thread thread1 = new Thread (counter::count);
thread1.start();

这是Java 8中功能接口的要点:您通常不需要显式实现它们,因为与接口唯一的非默认方法签名匹配的lambda表达式(包括方法引用)可以充当界面的实现。