难以理解Java 8 Lambda

时间:2014-11-06 03:09:39

标签: java lambda java-8

private ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
    Thread t = new Thread(r);
    t.setDaemon(true); // allows app to exit if tasks are running
    return t ;
});

我理解执行者背后的想法但是,参数r让我很困惑。我用过:

 final ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        System.out.println("Class of r: " + r.getClass()+ ". r to string: " + r.toString());
        System.out.println("Class of t: " + t.getClass() +". Name of t: "+ t.getName());
        t.setDaemon(true);
        return t;
    });

深入挖掘,结果是:

Class of r: class java.util.concurrent.ThreadPoolExecutor$Worker. r to string: java.util.concurrent.ThreadPoolExecutor$Worker@1dc3963[State = -1, empty queue]
Class of t: class java.lang.Thread. Name of t: Thread-3

r作为参数传递给Thread对象构造函数。

  1. 简单字母r如何表明传递的对象是ThreadPoolExecutor
  2. ThreadPoolExecutor如果没有按照Runnable构造函数的要求实现Thread's,如何作为参数传递?
  3. 如果有人能为我提供非lambda版本的代码,那么对我的理解将会非常有益。

1 个答案:

答案 0 :(得分:15)

newSingleThreadExecutor将ThreadFactory作为参数。 ThreadFactory定义了一个方法newThread,它将Runnable作为参数并返回一个Thread。

如果我们明确指定r的类型,那么lambda可能会更有意义:

(Runnable r) -> {
    Thread t = new Thread(r);
    return t;
}

现在更明显的是,这是newThread的主体定义。

由于lambda立即作为参数传递给接受ThreadFactory的方法,因此编译器能够推断出r的类型必须是Runnable。因此可以省略。

如果没有lambda,此代码将转换为以下匿名类定义和实例化:

private ExecutorService exec = Executors.newSingleThreadExecutor(
    new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    }
);
  

简单字母r如何表明传递的对象是ThreadPoolExecutor

r的类型是Runnable,因为lambda表达式的目标类型定义了它的单个方法。

您看到的对象实际上是ThreadPoolExecutor$Worker,它是实现Runnable的ThreadPoolExecutor的私有内部类。

  

ThreadPoolExecutor如果没有按照Runnable的构造函数的要求实现Thread,如何作为参数传递?

见上文(r是一个Runnable)。