多线程6

VB6多线程探秘 VB6稳定多线程,一直是争论很大的的。 比较稳定的多线程,一般使用 set MT=CreateObject("VbMT.MT") 但其他单元线程之间,是无法访问的,只有在创建者中,才可使用该对象MT.   还有一个问题,如果设置单元线程停止,一般通过设置属性,比如MT.bStop=True,设停止参数, 然后再单元线程中通过检测bStop而退出的。 但问题来了,如果单元线程挂起,通过 阅读详情

线程池 

标准库中的线程池

     ExecutorService service=Executors.newCachedThreadPool();//根据任务数目,自动进行扩容 
     Executors.newFixedThreadPool(4);//创建固定线程数目的线程池
     Executors.newSingleThreadExecutor();//创建一个只包含单个线程的线程池
     Executors.newScheduledThreadPool(4);//创建一个固定的线程数,但是任务演示执行的线程池。

 线程池的应用

    public static void main(String[] args) {
        ExecutorService service=Executors.newCachedThreadPool();//根据任务数目,自动进行扩容
      for (int i=0;i<10000;i++) {
         
          service.submit(new Runnable() {
              @Override
              public void run() {
                  System.out.println( i+ Thread.currentThread().getName());
              }
          });

      }

上述中 i  存在问题,这是变量捕获问题,i一直在改变不能在print中使用,所以更改代码如下

   public static void main(String[] args) {
        ExecutorService service=Executors.newCachedThreadPool();//根据任务数目,自动进行扩容
      for (int i=0;i<10000;i++) {
          int id=i;
          service.submit(new Runnable() {
              @Override
              public void run() {
                  System.out.println( id+ Thread.currentThread().getName());
              }
          });

      }

创建线程池

一个线程池要包含哪些东西?

1)有若干个线程

2)有任务队列.(使用Runnable即可)

3)提供submit方法



import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;

class  MyThreadPool{
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    public  MyThreadPool(int n){
    for (int i=0;i<n;i++){
        Thread t=new Thread(()->{
         while (true) {
             try {
                 Runnable runnable = queue.take();
                 runnable.run();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
        });
        t.start();
    }
    }
    void subimt(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
}
public class Test1 {
    public static void main(String[] args) {
        MyThreadPool threadPool=new MyThreadPool(10);

        for(int i=0;i<1000;i++){

            int id=i;
            try {
                threadPool.subimt(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println( id+ Thread.currentThread().getName());
                    }
                });
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
    }

}

main线程的任务是先是创建对象,通过调用MyThreadPoll的构造方法来创建n个线程,然后各个线程进入无限循环,然后等到有任务进入,然后通过sbimt方法添加到任务队列queue,然后到任务队列,任务队列将其分布到各个线程最后达到线程池的作用。


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;

class  MyThreadPool2{
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
        private  int maxPoolSize=50;
        private List<Thread> threadList=new ArrayList<>();
    public  MyThreadPool2(int n,int maxPoolSize){
            this.maxPoolSize=maxPoolSize;
        for (int i=0;i<n;i++){
            Thread t=new Thread(()->{
                while (true) {
                    try {
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        threadList.add(t);
        }
    }
    void subimt(Runnable runnable) throws InterruptedException {
            //此处进行判定,判定说当前任务队列的元素个数,是否比较长
        //如果队列元素比较长,说明已有的线程,不太能处理过来了、创建新的线程即可,
        // 如果队列不是很长,没必要创建新的线程.
        queue.put(runnable);
        if(queue.size()>=500&& threadList.size()<maxPoolSize ){

                Thread t=new Thread(()->{
                    while (true) {
                        try {
                            Runnable take = queue.take();
                            runnable.run();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
                t.start();
            }

    }
}
public class Test2 {
    public static void main(String[] args) {
        MyThreadPool2 threadPool2=new MyThreadPool2(20.10);

        for(int i=0;i<1000;i++){

            int id=i;
            try {
                threadPool2.subimt(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println( id+ Thread.currentThread().getName());
                    }
                });
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
    }

}

可以将线程数加入对应的队列,然后就可以实现最大线程的限制,但是最大线程的限制条件在submit函数中应用

实现拒绝策略的核心,在submit这里

2)submit的时候,先判定当前任务队列元素是否已经比较多了(自行设定一个阈值,比如,900)

3)如果确实比较多了,就根据刚才构造时指定的拒绝策略,执行不同的逻辑,

a)直接抛出异常,

b)直接在submit中调用Runnable的run.

c)删除队列的队首元素 (可以一次删多个,也不一定是一个)

d)丢弃当前元素,不添加到队列中.

定时器

定时器,就是“闹钟"效果

指定一个任务(Runnable),并且指定一个时间(3000ms),此时这个任务不会立即执行,而是在时间到达之后,再去执行。

定时器的应用

第一个参数是一个抽象类,本质上还是实现了Runnable.就把它当做Runnable来使用即可.


import java.util.Timer;
import java.util.TimerTask;

public class Test3 {
    public static void main(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(3000);
            }
        },3000);
    }
}

线程不会结束,由于Timer中包含了前台宪政,阻止了进程的结束。

(TimerTasktask,longdelay)

表示"多长时间之后”执行.以当前执行schedule的时刻为基准,继续等delay时间之后再去进一步的执行.

创建定时器

需求:

1)能够延时执行任务/指定时间执行任务

2)能够管理多个任务

1.定义一个类,表示一个任务(Runnable)
class MyTimerTask{
    private  Runnable runnable;
    private long time;
    public  MyTimerTask(Runnable runnable){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+time;
    }
    public void run(){
        runnable.run();
    }
    public  long getTime(){
        return time;
    }
}
2.通过一定的数据结构,保存多个任务,
class MyTimer{
    private List<MyTimerTask> taskList=new ArrayList<>();
    public void schedule(Runnable runnable,long delay){
        MyTimerTask timerTask=new MyTimerTask(runnable,delay);
        taskList.add(timerTask);

    }
}

 这样会造成不停的扫描操作,这样会消耗太多资源,可以应用优先级队列。

可以把这些任务通过优先级队列保存起来.按照时间作为优先级的先后的标准就可以做到,队首元素就是时间最靠前的任务

class MyTimer{
    private PriorityQueue<MyTimerTask> taskList=new PriorityQueue<>();
    public void schedule(Runnable runnable,long delay){
        MyTimerTask timerTask=new MyTimerTask(runnable,delay);
        taskList.add(timerTask);

    }
}
3.还需要有一个线程,来负责执行这里的任务.(在指定的时间去执行)

构造方法中,创建一个线程,用新的线程来执行队列中的任务,

public MyTimer(){
        Thread thread=new Thread(()->{
           while (true){
               if(taskList.size()==0){
                   continue;
               }
               MyTimerTask timerTask=taskList.peek();
               long curTime=System.currentTimeMillis();
               if(curTime>=timerTask.getTime()){
                   taskList.poll();
               }else {
                   continue;
               }
           }
        });
    }

优化,会有线程安全所以要加锁,要不然会出现重复扫描的问题。

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

class MyTimerTask{
    private  Runnable runnable;
    private long time;
    public  MyTimerTask(Runnable runnable, long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;
    }
    public void run(){
        runnable.run();
    }
    public  long getTime(){
        return time;
    }
}
class MyTimer{
    Object o=new Object();
    private PriorityQueue<MyTimerTask> taskList=new PriorityQueue<>();
    public void schedule(Runnable runnable,long delay){
        synchronized (o) {
            MyTimerTask timerTask = new MyTimerTask(runnable, delay);
            taskList.add(timerTask);
        }
    }
    public MyTimer(){

        Thread thread=new Thread(()->{
           while (true) {
               synchronized (o) {
                   if (taskList.size() == 0) {
                       continue;
                   }
                   MyTimerTask timerTask = taskList.peek();
                   long curTime = System.currentTimeMillis();
                   if (curTime >= timerTask.getTime()) {
                       taskList.poll();
                   } else {
                       continue;
                   }
               }
           }
        });
        }
    }

}

现在存在忙等状态

上述代码就会短时间内循环很多次.上述操作都是在王"空转”一直在持续消耗cpu,但是没有真正执行任务。

 try {
                           o.wait(curTime-timerTask.getTime());
                       } catch (InterruptedException e) {
                           throw new RuntimeException(e);
                       }

此处应用wait方法不用sleep

1.notify唤醒wait,属于常规编程手法(处理正常业务流程)通过interrupt唤醒sleep,非常规手法.(处理异常业务流程)

2.sleep会抱锁,wait不会抱锁

这个代码中,不太适合直接使用PriorityBlockingQueue

只能处理,队列为空时候的阻塞,如果使用上述阻塞版本,还需要通过额外的锁对象和wait来实现针对时间未到的情冰

比较肯定要写构造方法:如下

最终写出的个人task如下:

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

class MyTimerTask implements Comparable<MyTimerTask>{
    private  Runnable runnable;
    private long time;
    public  MyTimerTask(Runnable runnable, long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;
    }
    public void run(){
        runnable.run();
    }
    public  long getTime(){
        return time;
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int) (this.time-o.time);
    }
}
class MyTimer{
    Object o=new Object();
    private PriorityQueue<MyTimerTask> taskList=new PriorityQueue<>();
    public void schedule(Runnable runnable,long delay){
        synchronized (o) {
            MyTimerTask timerTask = new MyTimerTask(runnable, delay);
            taskList.add(timerTask);
        }
    }
    public MyTimer(){

        Thread thread=new Thread(()->{
           while (true) {
               synchronized (o) {
                   if (taskList.size() == 0) {
                       continue;
                   }
                   MyTimerTask timerTask = taskList.peek();
                   long curTime = System.currentTimeMillis();
                   if (curTime >= timerTask.getTime()) {
                       taskList.poll();
                   } else {
                       try {
                           o.wait(curTime-timerTask.getTime());
                       } catch (InterruptedException e) {
                           throw new RuntimeException(e);
                       }
                   }
               }
           }
        });
        }
    }

}
public class Test4 {
    public static void main(String[] args) {

    }
}

Qt6 for C++ 多线程 Qt6提供了多种线程管理方式,主要通过QThread类及其相关机制实现多线程编程。核心概念包括QThread类、线程安全信号槽机制、线程局部存储、同步原语(如QMutex、QReadWriteLock等)、线程池、事件循环、线程亲和性以及线程退出与清理。QThread类支持通过继承或moveToThread()方式创建线程,并提供start()、quit()等方法控制线程生命周期。 阅读详情

相关推荐

【Redis】 - Redis 6.0 新特性之多线程模型

在执行命令阶段:Redis是单线程来执行命令的,每一条到达读服务端的命令并不会立即执行,所有的命令都会进入一个 socket 任务队列中,当 socket 可读则交给单线程事件分发器逐个被执行,即一个线程处理所有网络请求。如下图所示:从Redis 4.0 以后并不是严格意义上的单线程,除了主线程外,Redis 也有后台线程或子进程处理一些其他较为缓慢的操作(例如:无用连接的释放、慢IO访问和一些其他类似操作 - 清理脏数据、生成快照、AOF重写等)。

迪曼奥特迦-博客 4854

Redis 6.0多线程模型总结

前言:Redis 6.0.1 于 2020 年 5 月 2 日正式发布了,如 Redis 作者 antirez 所说,这是迄今为止最“企业”化的版本,也是有史以来改动最大的一个 Redis 版本。这个版本提供了诸多令人心动的新特性及功能改进,比如新网络协议RESP3,新的集群代理,ACL等,其中关注度比较高的应该是多线程模型了。 1、Redis6.0之前的版本真的是单线程吗? Redis在处理客户端的请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的

何哥的博客 7121

VB6环境下的多线程编程实战指南

线程函数是多线程编程中的核心概念,它定义了线程将执行的代码。在Visual Basic 6.0(VB6)中,线程函数通常是一个标准的子程序,但有以下特点和定义规则:无返回值:线程函数不返回任何值。参数传递:可以通过参数将数据传递给线程函数,但这些参数必须是值类型或通过值传递的引用类型。全局变量访问:线程函数可以访问全局变量,但应当注意线程安全问题。调用API:通常通过Windows API函数如来启动一个线程函数。定义线程函数时,需要使用。

weixin_42181686的博客 938

redis6的多线程原理

Redis 6.0 的多线程是**“单线程命令执行 + 多线程网络 I/O”**的混合模型,核心是通过并行处理网络数据读写突破 I/O 瓶颈,同时保留单线程命令执行的简单性和安全性。这种设计在高并发场景下可提升 2-3 倍的吞吐量,尤其适合大流量、多连接的 Redis 部署。

青鱼入云的博客 1264

5分钟搞定:用Ollama在MacBook上本地运行Qwen3大模型(附避坑指南)

本文详细介绍了如何在MacBook上使用Ollama快速部署和运行Qwen3大模型,包括安装步骤、性能优化技巧及常见问题解决方案。Ollama作为一款轻量级工具,特别适合M系列芯片的Mac用户,支持多种量化版本,显著降低资源消耗,提升推理速度。

sql99的博客 822

揭秘cocos-mcp:如何用AI助手提升CocosCreator游戏开发效率

本文深入介绍了cocos-mcp工具,它作为连接AI助手与CocosCreator编辑器的桥梁,遵循MCP协议,能显著提升游戏开发效率。通过自然语言指令,开发者可让AI直接查询场景结构、批量修改属性或生成上下文代码,将重复操作变为智能调度,实现从“手动操作者”到“指令指挥官”的工作流变革。

weixin_29001683的博客 1048

用VB6实现多线程

用VB6实现多线程 【下载地址】用VB6实现多线程 此项目提供了一份用VB6(Visual Basic 6)实现的稳定多线程源码,适用于仍在维护老旧系统或特定场景的开发需求。通过深入调用Windows操作系统的API,源码在VB6环境中实现了多线程功能,显著提升程序执行效率。源码经过充分测试,稳定性强,且代码注释详尽,便...

gitblog_06784的博客 381

2025年12月11日 Coherent收发器下沉到数据中心:调研

技术可行性已基本具备。随着3nm DSP技术的成熟和Coherent-Lite等低功耗方案的推出,Coherent技术与IMDD的功耗差距在800G及以上速率节点快速缩小。特别是在1.6T及更高速率,两种技术的功耗开始趋于收敛。同时,通过系统级优化,如将DSP功能从可插拔模块转移到ASIC芯片,可实现30%以上的功耗降低。在成本方面,硅光技术的进步使得单通道硅光引擎BOM成本降至18美元,较2020年下降62%,逼近InP方案的经济临界点。光学系统机会丰富多样。

weixin_51184047的博客 1167

Redis6为什么引入了多线程?

Redis 6 引入多线程技术,是为了应对日益增长的高并发和大规模数据存储的需求。通过将网络 I/O 和持久化等操作进行多线程化,Redis 6 能够更好地利用现代多核处理器的优势,提高性能和吞吐量。然而,这种多线程设计依然保留了 Redis 核心单线程模型的优点,确保了操作的顺序性和数据的一致性。多线程的引入使得 Redis 在高负载、低延迟场景下表现更加出色,但也要求开发者对系统性能进行精细调优,以便最大化地发挥多线程的优势。

kangbin825的专栏 1015

新手避坑指南:HT7036计量芯片SPI读取电压的完整流程(从复位到校准)

本文详细介绍了HT7036计量芯片的SPI读取电压完整流程,从硬件准备到校准设置,重点解析了复位引脚处理、SPI通信配置、芯片初始化及数据处理等关键步骤。针对常见问题如晶振焊接、SPI时序错误等提供实用解决方案,帮助开发者高效完成电压测量与校准。

weixin_30070339的博客 326

手把手教你用Python+Playwright实现抖音/B站/视频号三平台自动上传(附完整配置流程)

本文详细介绍了如何使用Python和Playwright构建一个多平台视频自动化上传系统,涵盖抖音、B站和视频号三大平台。文章从环境搭建、身份验证持久化、平台特异性上传引擎设计到任务调度与错误处理,提供了完整的配置流程和实战代码,帮助开发者实现高效、稳定的批量上传功能。

weixin_29294975的博客 1147

【QT教程】QT6多线程编程 QT多线程编程

QT6线程概述QT6线程概述在软件开发过程中,多线程编程是一项核心且至关重要的技能,尤其是在需要处理大量数据或进行复杂计算时。QT6作为一套成熟的跨平台C++应用程序框架,提供了强大的线程支持,使得多线程编程更加简洁易行。QT6中线程的基本概念在QT6中,线程主要是通过QThread类来实现的。QThread是一个能够运行和管理的线程类,它提供了低层次的线程控制,比如线程的启动、停止和线程间的通信等。为什么使用多线程多线程编程的主要优势在于它可以提高应用程序的响应性和性能。

QT性能优化QT原理源码QT界面美化 1479

保姆级教程:用Cesium的Primitive API实现火箭发射全流程动画(含代码避坑)

本文详细介绍了如何使用Cesium的Primitive API实现火箭发射全流程动画,包括模型控制、关节动画和精细时序管理。通过实战代码示例和性能优化技巧,帮助开发者高效构建高复杂度航天仿真系统,显著提升三维可视化效果与运行效率。

weixin_42565652的博客 212

【QT教程】QT6多线程编程

QT6线程概述QT6线程概述在软件开发中,多线程编程是一项核心技能,它能够帮助开发者充分利用现代多核处理器的性能优势,提高应用程序的响应性和性能。Qt,作为一个成熟的跨平台C++图形用户界面库,提供了强大的线程支持,使得多线程编程变得更加简洁和高效。Qt6是Qt系列的最新版本,它在多线程方面带来了一些新的特性和改进。Qt6中的线程改动在Qt6中,线程相关的API经历了一些重要的改动,主要包括,QThread,Qt6中对QThread类进行了重构,简化了线程的创建和管理。

QT性能优化QT原理源码QT界面美化 1533

【案例讲解】LVGL关于旋转的配置

在实现项目中,因为横竖屏的关系,需要对其做90度的旋转。配置旋转时发现一些局部刷新控件,旋转后效果不对。异常图标正常图标。

Bigan(安)的博客 4284

实战全解|大疆司空2二次开发:从接口开发到第三方业务系统深度融合

大疆司空2二次开发是实现行业无人机定制化应用的关键,通过OpenAPI后端对接+前端组件集成的组合方式,可快速完成功能定制,而与第三方业务系统的深度融合,能彻底打通“业务下发-设备执行-数据回传-流程闭环”的全链路,让无人机管控真正融入行业业务流程。开发过程中,建议优先采用私有版部署保障数据安全,通过中间适配层降低系统耦合度,结合实际业务场景打磨功能,避免过度开发。随着大疆开发者生态的完善,司空2的二次开发能力将持续升级,为更多行业无人机应用提供技术支撑。

2501_93651177的博客 966

Redis6 多线程模型

线程,都同时处理图中的“队列”,是不是会存在锁竞争的关系尼?还需要注意的是,线程数并不是越大越好,官方认为超过了。,并对数据进行协议解析,当队列全部处理完毕后,主线程会对队列中请求串行“执行。官方建议:只在机器至少有4个内核时才启用多线程模型,且至少留下一个备用内核。【6】主线程执行所有命令并清空整个等待队列,等待客户端后续的请求队列;件事情串行一起执行,因为是基于内存,所以执行速度非常快。开启多线程后,还需要设置线程数,否则是不生效的。和串行操作,某个操作“出问题”会“阻塞”后续操作。

程序猿进阶 2719

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Redis 6.0多线程

Redis 6.0多线程 前段时间无意间看到一篇博客,讲述了Redis6即将在年底发布的事情,好奇心驱动下搜索了官网,想看看新版Redis带来了什么新的功能,果然得到证实Redis在年底将发布新的版本:6.0,并且Redis创始人兼核心开发者 antirez 在博客也介绍了将在6.0所提供的新功能 ACL用户权限控制功能 RESP3:新的 Redis 通信协议 Cluster 管理工具 SSL 支持 IO多线程支持 新的Module API 新的 Expire 算法等 具体可以参考相关资料(http://a

lizhengze1117的博客 4984

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Redis6为什么引入了多线程?

Redis6为什么引入了多线程?

java1234的博客 1054

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Redis6 终于还是迎来了多线程版本!

知道的越多,不知道的就越多,业余的像一棵小草!编辑:业余草来源:https://www.xttblog.com/?p=4990今天是 5 月 3 号,五一假期已经过半,相信不少人假期余额...

xmt1139057136的专栏 8675

稳定方便实用的VB6多线程技术及示例:让VB6开发如虎添翼

稳定方便实用的VB6多线程技术及示例:让VB6开发如虎添翼 去发现同类优质开源项目:https://gitcode.com/ 在众多编程语言中,Visual Basic 6.0(简称VB6)因其易用性和高效性,依然受到许多开发者的青睐。但是,在处理一些需要并行执行的任务时,VB6的单一执行线程可能显得力不从心。今天,我们就来为大家推荐一款稳定、方便、实用的VB6多线程技术及示例,助您轻松应对复杂编...

gitblog_06757的博客 749

PySide6多线程-QThread

Pyside6多线程-QThread,通过实例化工作线程和 moveToThread 方式实现

YumOS的博客 2058

突破:VB6中使用安全多线程

    旧瓶装新酒,老树开新花。    遥想当年研究vb6中的多线程,为求解而网际上四处奔波、八方碰壁,程序的一次次崩溃无情的摧残和消磨着我的耐心、精力和时间,被折磨的简直没有人样。匆匆数年,这个问题就像邻家女孩般始终在心里悄悄的占据着一席之地。时至今日忆起往昔,独怆然而泣下之老泪纵横有过之而无不及。唉,往事不堪回首......    说书唱戏劝人芳,三条大道走中央,善恶到头终有报,人间正道是沧桑

迈克揉索芙特 1万+

Redis6.0多线程的疑惑解答

Redis在处理客户端的请求是,包括获取(socket读)、解析、执行、内容返回(socket 写)等都有一个顺序串行的主线程处理,这就是所谓的"单线程"。但如果严格来讲并不是单线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大key的删除等等。

Cover_sky的博客 1199
上一篇: 多线程5
下一篇: 多线程7
鱼裤
博客等级 码龄4年 678粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼裤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值