异步那些事01

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

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");

    }

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】——并发控制

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

Vapor Mode:Vue.js 的速度与激情,代码界的闪电侠

大家好&#xff0c;我是宝哥。 在快速发展的网络开发世界中&#xff0c;创新的Vue.js团队给我们带来了Vapor Mode。这个新模式优化了Vue的核心渲染过程&#xff0c;帮助我们的应用程序像轻烟一样运行&#xff0c;开发者无需深入复杂的优化工作。 在这篇文章中&#xff0c;我们将…

贝叶斯算法:机器学习中的“黄金法则”与性能提升之道

&#x1f440;传送门&#x1f440; &#x1f50d;机器学习概述&#x1f340;贝叶斯算法原理&#x1f680;贝叶斯算法的应用✨文本分类✨医疗系统 &#x1f496;贝叶斯算法优化✨贝叶斯算法优化的主要步骤✨贝叶斯算法优化的优点✨贝叶斯算法优化的局限性 &#x1f697;贝叶斯算…

详细分析tcping的基本知识以及用法

目录 前言1. 安装配置2. 基本知识3. Demo 前言 针对ping的基本知识推荐阅读&#xff1a;详细分析ping的基本知识以及常见网络故障的诊断&#xff08;图文解析&#xff09; 1. 安装配置 针对Window的下载如下&#xff1a; 安装路径&#xff1a;tcping官网 下载tcping.exe&a…

【开源】大学生竞赛管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、系统介绍 学生管理模块 教师管理模块 竞赛信息模块 竞赛报名模块 二、系统截图 三、核心代码 一、系统介绍 基于Vue.js和SpringBoot的大学生竞赛管理系统&#xff0c;分为管理后台和用户网页端&#xff0c;可以给管理员、学生和教师角色使用&#xff0c;包括学…

STM32手写超频到128M函数

今天学习了野火的STM32教程学会了如何设置STM32的时钟频率&#xff0c;步骤比较详细&#xff0c;也很容易理解&#xff0c;就是视频教程不能跳着看&#xff0c;只能一节节的看&#xff0c;不然会知识不连贯&#xff0c;造成有些知识不理解&#xff0c;连续着看还是没有什么难度…

闲置商标转让出现这些状态时注意!

近日以前做转让的一个朋友的商标转让证明下来&#xff0c;正好是2个半月&#xff0c;普推知产老杨发现这个时间也太快&#xff0c;以前差不多四个月左右&#xff0c;有些朋友需要购买闲置商标&#xff0c;3个月内所有权就变成自己的。 在购买闲置商标时要注意有一些细节&#x…

创新实训2024.05.26日志:服务端接口实现——用户开启多个会话

1. 概念图 类似于Kimi&#xff0c;文心一言&#xff0c;chatGPT等市面上主流的大模型&#xff0c;我们的大模型也支持同一个用户的多个会话&#xff0c;并且提供支持联系上下文给出解答的能力。 2. 基于会话的对话 在langchain chatchat这个对langchain框架进行二次封装的第三…

GPT-4 与 GPT-4 Turbo有什么区别?

在不断发展的人工智能和自然语言处理领域&#xff0c;OpenAI 的 GPT 系列一直走在最前沿&#xff0c;彻底改变了机器理解和生成类人文本的方式。每一次迭代&#xff0c;进步都会突破可能性的界限。 最新的条目 GPT-4 和 GPT-4 Turbo 引起了人工智能社区内外的极大兴趣和争论。…

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展&#xff0c;它的主要作用是提供一个本地开发服务器&#xff0c;以便实时预览和调试网页应用程序。其最大特点在于热重载&#xff0c;即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…

【C++】详解深浅拷贝的概念及其区别

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Visual Studio 2022 目录 什么是拷贝 什么是浅拷贝 什么是深拷贝 深浅拷贝的区别及使用场景 结语 什么是拷贝 在C编程中&#xff0c;拷贝是一个非常重要的概念&#xff0c;对于理解和使用类和对象起…

浅谈JMeter体系结构

JMeter体系结构详解 JMeter是一款功能强大的开源性能测试工具&#xff0c;广泛应用于Web应用、数据库、FTP服务器等多种场景下的负载和压力测试。其灵活的体系结构设计使得测试计划的创建、执行与结果分析变得高效而直观。本文将深入解析JMeter的三维空间体系结构&#xff0c;…

C++实现定长内存池

项目介绍 本项目实现的是一个高并发的内存池&#xff0c;它的原型是Google的一个开源项目tcmalloc&#xff0c;tcmalloc全称Thread-Caching Malloc&#xff0c;即线程缓存的malloc&#xff0c;实现了高效的多线程内存管理&#xff0c;用于替换系统的内存分配相关函数malloc和fr…

基于UDP的TFTP文件传输-实现网盘上传下载功能

数据传输模式&#xff1a;octet(二进制模式) #include<head.h> char* down_up_request(char* buf,char* filename,int rw,int sockfd,struct sockaddr_in in); int download(struct sockaddr_in in,char* filename,char* buf,int sockfd); int upload(struct sockaddr_in…

数据结构(七)查找

2024年5月26日一稿(王道P291) 7.1 查找的基本概念 7.2 顺序查找和折半查找 7.2.1 顺序查找 7.2.2 折半查找 7.2.3 分块查找 7.3 树形查找 7.3.1 二叉排序树(BST)

FFmpeg+QT播放器实战1---UI页面的设计

1、播放器整体布局的设计 该部分使用QT的UI工具&#xff0c;进行整体页面设置&#xff0c;如下图1所示&#xff1a; 2、控制布局的设计 创建ctrBar的UI页面并进行页面布局设置&#xff0c;如下图2所示&#xff1a; 将图1中ctrBarWind对象提升为ctrBar类(该界面替代原先的控…

Modbus TCP转Profinet网关测试配置案例

本案例采用XD-ETHPN20网关做为Modbus TCP通信协议设备与Profinet通信协议设备连接的桥梁。Modbus TCP是一种基于TCP/IP协议的工业通信协议&#xff0c;而Profinet则是用于太网通信的协议。Modbus TCP转Profinet网关可实现这两种不同协议之间的数据交换和传输&#xff0c;极大地…

实在智能TARS:面向垂直领域自主训练的类GPT大模型

一、写在前面 在数字化浪潮的推动下&#xff0c;企业正寻求突破传统生产力的局限&#xff0c;以实现更高效、更智能的运营模式。实在智能科技有限公司的TARS产品&#xff0c;以其前沿的人工智能技术&#xff0c;为企业注入了新质生产力&#xff0c;引领着智能化转型的新潮流。…

数据结构(三)循环链表

文章目录 一、循环链表&#xff08;一&#xff09;概念&#xff08;二&#xff09;示意图&#xff08;三&#xff09;操作1. 创建循环链表&#xff08;1&#xff09;函数声明&#xff08;2&#xff09;注意点&#xff08;3&#xff09;代码实现 2. 插入&#xff08;头插&#x…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十二)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…