异步那些事01

news2024/11/19 1:34:30

首先我们肯定先说创建线程

1.继承Thread类

o定义一个类MyThread继承Thread类
o在MyThread类中重写run()方法
o创建MyThread类的对象
o启动线程

package Java.thread;

public class first extends  Thread{
    public  void run(){
        for(int i=0;i<50;i++){
            System.out.println("我是小线程"+"名称:"+getName()+",运行结果:"+i);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

package Java.thread;

public class test {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("我是主线程");
        first f1=new first();
        first f2=new first();
        f1.start();
        f2.start();
        Thread.sleep(50);
        System.out.println("主线程结果。");
    }
}

请添加图片描述
2.实现Runnable接口

o定义一个类MyRunnable实现Runnable接口
o在MyRunnable类中重写run()方法
o创建MyRunnable类的对象
o创建Thread类的对象,把MyRunnable对象作为构造方法的参数
o启动线程

package Java.thread;

public class second implements Runnable{
    public void run(){
        for(int i=0;i<50;i++){
        //不能直接获取getname,因为不是继承
            System.out.println("我是小线程"+"名称:"+Thread.currentThread().getName()+",运行结果:"+i);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

package Java.thread;

public class test {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("我是主线程");
   second s1=new second();
   second s2=new second();
   Thread t=new Thread(s1,"小线程1");
   Thread t1=new Thread(s2,"小线程2");
   t.start();
   t1.start();
   Thread.sleep(50);
   System.out.println("主线程结果。");
    }
}

请添加图片描述
使用lambda简化:

package Java.thread;

public class test {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("我是主线程");
        Runnable s1=()->{
            for(int i=0;i<50;i++){
            //不能直接获取getname,因为不是继承
            System.out.println("我是小线程"+"名称:"+Thread.currentThread().getName()+",运行结果:"+i);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }};
   Thread t=new Thread(s1,"小线程1");
   Thread t1=new Thread(s1,"小线程2");
   t.start();
   t1.start();
   Thread.sleep(50);
   System.out.println("主线程结果。");
    }
}

3.实现Callable接口

  • V call() 计算结果,如果无法计算结果,则抛出一个异常
  • FutureTask(Callable callable) 创建一个
    FutureTask,一旦运行就执行给定的 Callable
  • V get() 如有必要,等待计算完成,然后获取其结果

o定义一个类MyCallable实现Callable接口
o在MyCallable类中重写call()方法
o创建MyCallable类的对象
o创建Future的实现类FutureTask对象,把MyCallable对象作为构造方法的参数
o创建Thread类的对象,把FutureTask对象作为构造方法的参数
o启动线程
o再调用get方法,就可以获取线程结束之后的结果。

package Java.thread;

import java.util.concurrent.Callable;

public class thired implements Callable {
    @Override
    public Object call() throws Exception {
        for(int i=0;i<50;i++){
            System.out.println("我是小线程"+"名称:"+Thread.currentThread().getName()+",运行结果:"+i);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        String o="callable";
        return o;
    }
}

public class test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
   thired s1=new thired();
   thired s2=new thired();
   FutureTask f1=new FutureTask(s1);
   FutureTask f2=new FutureTask(s2);
   Thread t=new Thread(f1,"小线程1");
   Thread t1=new Thread(f2,"小线程2");
   t.start();
   t1.start();
   System.out.println("小线程1结果"+f1.get());
   System.out.println("小线程2结果"+f2.get());
   System.out.println("主线程结果。");
    }
}

请添加图片描述
System.out.println(“主线程结果。”); 并不是在所有其他线程都完成之后才执行的,而是取决于 f1.get() 和 f2.get() 的调用顺序和它们的行为。
FutureTask.get() 方法用于获取异步计算的结果。如果计算尚未完成,此方法将阻塞直到它完成。这意味着,如果 f1 或 f2 对应的线程尚未完成其任务,get() 方法将阻塞主线程,直到该任务完成。
主线程会首先等待 f1 完成,然后再等待 f2 完成。

o实现Runnable、Callable接口
o好处: 扩展性强,实现该接口的同时还可以继承其他的类
o缺点: 编程相对复杂,不能直接使用Thread类中的方法
o继承Thread类
o好处: 编程比较简单,可以直接使用Thread类中的方法
o缺点: 可以扩展性较差,不能再继承其他的类

CompletableFuture引入

Future有几个局限,Java1.8就推出了加强版的Future类:CompletableFuture。

来上几个future的局限的代码(部分,下一节重点是completablefuture):
1.阻塞主进程的执行:


public class test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //自定义线程池 ,使用自定义的拒绝策略
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 60,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));
           Callable callable=()->{
               System.out.println(Thread.currentThread().getName()+":任务执行中");
               Thread.sleep(600);
               return "任务执行完成";
           };

           Future f=threadPoolExecutor.submit(callable);
           System.out.println("任务执行中");
           System.out.println(f.get());
           System.out.println("阻塞我的主进程了吗???,我看看");
           threadPoolExecutor.shutdown();
    }
}

请添加图片描述

改为completableFuture:

import java.util.concurrent.*;

public class test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //自定义线程池 ,使用自定义的拒绝策略
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 60,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));
           Callable callable=()->{
               System.out.println(Thread.currentThread().getName()+":任务执行中");
               Thread.sleep(600);
               return "任务执行完成";
           };

      CompletableFuture<String> completableFuture=  CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+":任务执行中");
          try {
              Thread.sleep(600);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          return "任务执行完成";

        },threadPoolExecutor);
        //注册一个回调函数来处理结果
        completableFuture.thenAccept(re-> {
            System.out.println("任务完成结果:"+re);
        });
        System.out.println("其他进程执行中");
        threadPoolExecutor.shutdown();
    }


}

请添加图片描述

2.链式调用上:

futuretask不能链式调用,任务2无法用任务1的结果


public class test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //自定义线程池 ,使用自定义的拒绝策略
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 60,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));

         Future <String> future=threadPoolExecutor.submit(()->{
             try {
                 Thread.sleep(60);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             return "任务1完成";
         });

         Future <String> future1=threadPoolExecutor.submit(()->{
             //我们想要在这个任务中使用 future 的结果,但我们不能直接链式调用
             try {
                 Thread.sleep(60);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             return "任务2完成";
         });

        System.out.println(future.get());
        System.out.println(future1.get());
        threadPoolExecutor.shutdown();
    }


}

completablefuture:


public class test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //自定义线程池 ,使用自定义的拒绝策略
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 60,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));

          CompletableFuture<String> completableFuture=CompletableFuture.supplyAsync(()->{
              try {
                  Thread.sleep(60);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              return "任务1完成";
          },threadPoolExecutor);


         CompletableFuture<String> completableFuture1=completableFuture.thenApplyAsync(re->{
             //我们想要在这个任务中使用 future 的结果,但我们不能直接链式调用
             try {
                 Thread.sleep(60);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             return "任务2完成并用了任务1的结果:"+re;
         },threadPoolExecutor);

        completableFuture.thenAccept(re->{
            System.out.println("任务1运行结果:"+re);
        });
        completableFuture1.thenAccept(re1->{
            System.out.println("r任务2运行结果:"+re1);
        });

        System.out.println("主线程的任务3");

    }

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1699663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

go ast语义分析实现指标计算器

什么是AST 首先我们要知道AST是什么&#xff08;Abstract Syntax Tree&#xff0c;AST&#xff09;&#xff0c;简称为语法树&#xff0c;是go语言源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构&#xff0c;树上的每个节点都表示源代码中的一种结构。 …

英语四级翻译练习笔记①——大学英语四级考试2023年12月真题(第一套)——用ChatGPT修改训练四级翻译

目录 引言&#xff08;必看&#xff09; 翻译原文 我的翻译 得分&#xff08;1-3分&#xff09; 原文&#xff1a; 你的翻译&#xff1a; 修改后的翻译&#xff1a; 详细错误讲解&#xff1a; 引言&#xff08;必看&#xff09; 这是一篇英语四级翻译的练习的专栏&…

Java刷题总结(面试)

1、String类 String不可变 java 中String是 immutable的&#xff0c;也就是不可变&#xff0c;一旦初始化&#xff0c;其引用指向的内容是不可变的。 也就是说&#xff0c;String str “aa”&#xff1b;str“bb”&#xff1b;第二句不是改变“aa”所存储地址的内容&#xf…

计算机毕业设计 | SSM汽车租赁系统(附源码)

1&#xff0c; 概述 1.1 课题背景 随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。用户生活水平的不断提高&#xff0c;日常生活中用户对汽车租赁系统方面的要求也在不断提高&#xff0c;需要汽车租赁系统查询的人数更是不断增加&#xff0c;使得汽车租赁系统的…

项目管理:敏捷实践框架

一、初识敏捷 什么是敏捷(Agile)?敏捷是思维方式。 传统开发模型 央企,国企50%-60%需求分析。整体是由文档控制的过程管理。 传统软件开发面临的问题: 交付周期长:3-6个月甚至更长沟通效果差:文档化沟通不及时按时发布低:技术债增多无法发版团队士气弱:死亡行军不关注…

数据库SQL语言实战(十)(最后一篇)

目录 前言 练习题 实验八 实验九 题目一 题目二 总结 前言 本篇练习题的重点有两个&#xff1a; 一、测试提交commit和回滚rollback的作用,了解锁等待、授权等知识。 二、学会复制表结构、学会插入数据&#xff0c;特别是学会如何避免重复插入&#xff0c;也就是如何避…

【云原生】K8s管理工具--Kubectl详解(一)

一、陈述式管理 1.1、陈述式资源管理方法 kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口kubectl 是官方的 CLI 命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为apiserver 能识…

实时通信的方式——WebRTC

文章目录 基于WebRTC实现音视频通话P2P通信原理如何发现对方&#xff1f; 不同的音视频编解码能力如何沟通&#xff1f;&#xff08;媒体协商SDP&#xff09;如何联系上对方&#xff1f;&#xff08;网络协商&#xff09; 常用的API音视频采集getUserMedia核心对象RTCPeerConne…

蓝桥杯物联网竞赛_STM32L071KBU6_关于size of函数产生的BUG

首先现象是我在用LORA发送信息的时候&#xff0c;左边显示长度是8而右边接收到的数据长度却是4 我以为是OLED显示屏坏了&#xff0c;又或者是我想搞创新用了const char* 类型强制转换数据的原因&#xff0c;结果发现都不是 void Function_SendMsg( unsigned char* data){unsi…

C语言系列文章 | 函数 (共 10209 字)

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 目录 函数的概念库函数自…

匠心独运的掺Si量子势垒策略,显著提升了AlGaN基深紫外LED出光率

WHU团队凭借匠心独运的三明治式掺Si量子势垒策略&#xff0c;显著提升了AlGaN基深紫外光LED的效率&#xff0c;这一创新成果为中国武汉大学的研究团队所取得。他们巧妙地设计出一种三明治状Si掺杂&#xff08;未掺杂&#xff09;方案&#xff0c;应用于Al0.6Ga0.4N量子势垒中&a…

Android硬件渲染流程

Android硬件渲染流程 一.渲染流程1.VSync信号的监听2.VSync信号触发绘制 二.渲染原理1.画布的获取1.1 画布的创建1.2 渲染指令列表的创建 2.绘制与渲染指令2.1 矩形的绘制2.2 硬件渲染指令2.3 节点的绘制 3.绘制的提交3.1 绘制结果的保存3.2 绘制结果的获取 4.层级的构建4.1 绘…

FFmpeg的流程

文章目录 前序代码结构FFmpeg.cffmpeg_opt.c 小结 前序 之前看过FFmpeg的各种命令&#xff0c;然后不是很理解。相信很多人都不是很理解&#xff0c;毕竟&#xff0c;单纯的去记住那些命令行本身就需要很大的内存&#xff0c;我们的大脑内存又有限&#xff0c;所以&#xff0c…

spring cloud alibaba sentinel 配置过程 流控 降级热点 授权

目录 1.基础理论 2.配置 3.加入依赖和配置文件 4.流控 1.基础理论 Sentinel是阿里开源的项目&#xff0c;提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。 丰富的应用场景 &#xff1a;Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心…

锁相环的一些学习笔记--(1)

下图两组1.2.3可以对应起来&#xff1b; 一些分析&#xff1a; 1.根据这个可知最后vco_voltage停在0.5v 参考资料&#xff1a; 1. Matlab https://www.bilibili.com/video/BV1bR4y1Z7Xg/?spm_id_from333.1296.top_right_bar_window_history.content.click&vd_source555…

windows 搭建 go开发环境

go语言&#xff08;或 Golang&#xff09;是Google开发的开源编程语言&#xff0c;诞生于2006年1月2日下午15点4分5秒&#xff0c;于2009年11月开源&#xff0c;2012年发布go稳定版。Go语言在多核并发上拥有原生的设计优势&#xff0c;Go语言从底层原生支持并发&#xff0c;无须…

Google Play 提示 “您的设备与此版本不兼容“ 解决方案

一、 问题概述Google Play提示“您的设备与此版本不兼容”&#xff0c;无法安装应用。 遇到问题的设备为Xiaomi Mi A3&#xff0c;查了下这台手机的基本信息&#xff0c;Android One系统&#xff0c;版本分为9.0、10.0、11.0。 二、 问题分析Google Play的过滤器 通常有以下5种…

2024-5-10-从0到1手写配置中心Config之Spring Value热更新

定义SpringValueProcessor处理类 实现BeanPostProcessor后置处理器接口&#xff0c;扫描所有的Spring value&#xff0c;保存起来。实现ApplicationListener接口&#xff0c;在配置变更时&#xff0c;更新所有的spring value 实现BeanPostProcessor后置处理器接口 实现postPr…

Value-Based Reinforcement Learning(1)

Action-Value Functions Discounted Return&#xff08;未来的reward&#xff0c;由于未来存在不确定性&#xff0c;所以未来的reward 要乘以进行打折&#xff09; 这里的依赖actions &#xff0c;和states 这里 Policy Function : &#xff0c;表达了action的随机性 S…

HILL密码

一&#xff1a;简介 Hill密码又称希尔密码是运用基本矩阵论原理的替换密码&#xff0c;属于多表代换密码的一种&#xff0c;由L e s t e r S . H i l l Lester S. HillLesterS.Hill在1929年发明。 二&#xff1a;原理 1.对于每一个字母&#xff0c;我们将其转化为对应的数字&am…