线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池

2023年 8月 13日 60.5k 0

线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池
Java线程创建的方式

  • 继承Thread类,重写run方法
  • 重写Runnable接口,交给Tread类静态代理实现
  • 实现Callable接口,用FutureTask封装
  • 实现Runnable接口,用FutureTask封装
  • 继承FutureTask类,重写run方法(猜想、偏方,你非要实现其实也可以,hhh)
  • 线程池创建

前三种创建方式

这里为了便于叙述,毕竟不是本次的重点,我直接上源码,没基础的可以去找些其他资料来补一补

 public class ThreadpoolApplication {
 ​
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         // 1. 继承Thread类实现
         Thread impl =new ThreadImpl();
         impl.start();
         // 2. 实现Runnable接口
         // 对于有 @FunctionalInterface 的类 or 接口,我们可以使用lambda表达式来简化,当然
         // 没有这个注解也可以,但是一定要符合函数式编程的规范
         //      1. 只能有1个待实现的方法
         //      2. 允许有默认方法
         //      3. 只能是接口
         // @FunctionalInterface 可有可无,但是为了规范建议写上,起一个标记作用,告诉编译器这是一个函数式接口
         // 可以让IDE帮你检测你的函数式接口是否符合规范
         Thread runnableImpl = new Thread(new Runnable() {
 ​
             // 这里可以用函数式接口lambda表达式来简写,具体的内容这里不做过多解释,
             // 你可以理解lambda实现为是对接口的简单实现,因为你用lambda返回的也是个Runnable实现对象
             // 后面我就直接用Lambda表达式来简写了。
             @Override
             public void run() {
 ​
             }
         });
 ​
         runnableImpl.start();
 ​
         // 实现Callable接口,带返回值
         FutureTask futureTask= new FutureTask(()->{
             return 1;
         });
         new Thread(futureTask).start();
         System.out.println(futureTask.get());
         Integer result=0;
 ​
         // 实现Runnable接口,带返回值
         futureTask=new FutureTask(()->{
 ​
         },result);
         new Thread(futureTask).start();
         futureTask.get();   // 其实这个值就是你设置的值,可以去看一下源码,这里只是为了方便任务管理
         
         return ;
     }
 ​
 }

浅说函数式编程 —— Lambda的魔法

大家可能对函数式编程有点懵,其实就是符合上面所说的规范

对于有 @FunctionalInterface 的类 or 接口,我们可以使用lambda表达式来简化,当然没有这个注解也可以,但是一定要符合函数式编程的规范

  • 只能有1个待实现的方法
  • 允许有默认方法
  • 只能是接口,抽象类也不行

@FunctionalInterface 可有可无,但是为了规范建议写上,起一个标记作用,告诉编译器这是一个函数式接口可以让IDE帮你检测你的函数式接口是否符合规范

比如这样子:

 @FunctionalInterface
 public interface MethodInterface {
     void print();
 ​
     default MethodInterface andThen(MethodInterface methodInterface){
         // 想一下有什么区别
         //  print();
         //  methodInterface.print();
         //  return methodInterface;
         return ()->{
             print();
             methodInterface.print();;
         };
         // 不用lambda表达式,那么就是在andThen里面进行执行的,每次执行andThen的时候都会自动执行print方法,而且总体上每次           
         // methodInterface.print()会执行两次,那么methodInterface.print()不写的话最后需要再执行一次applay
         // 如果你是使用的lambda表达式返回,那么返回的是一个全新的接口,如果我们需要链式调用完,那么在最后还要执行一下
         // print方法,当然你也可以选择实现一个end()方法来表示结束,相当于另外起一个名
     }
 }

其实上面的函数式接口和Cusumer一样,不过Cusumer多了一个判空的过程,除此之外还有另外几个常用的函数式接口(统一规范),如下:

Cusumer

 @FunctionalInterface
 public interface Consumer {
 ​
 ​
     void accept(T t);
 ​
 ​
     default Consumer andThen(Consumer

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论