为什么阿里巴巴Java开发手册禁止使用Executors创建线程池?

线程池的使用ThreadPoolExecutor 线程池意味着可以储存线程,并让池内的线程得以复用,如果池内的某一个线程执行完了,并不会直接销毁它有生命周期,可以存活一些时间,待到下一个任务来时,它会复用这个在等待中的线程,避免了再去创建线程增加的额外系统开销。CachedThreadPool∶:允许的创建线程数量为Integer .NAX_VALE,可能会创建大量的线程,我们知道每个线程默认情况下占1M的内存空间,如果线程非常多,内存资源将会被耗尽,从而导致OOM。创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。 阅读详情

在这里插入图片描述

在Java并发编程中,线程池是提高系统性能的关键组件,而Executors工厂方法提供了创建线程池的便捷途径。许多开发者习惯性地使用Executors.newFixedThreadPool()或Executors.newCachedThreadPool()来快速实现并发任务处理,殊不知这种看似便利的方式却暗藏巨大风险。

当你的应用在高峰期突然宕机,日志中出现大量OOM异常时,你是否想过罪魁祸首可能是那几行看似无害的Executors代码?这正是为什么《阿里巴巴Java开发手册》将"禁止使用Executors创建线程池"列为强制性规范。

在这里插入图片描述

一、为什么禁止使用Executors工厂方法

1、资源耗尽风险

newFixedThreadPool和newSingleThreadExecutor,内部使用无界的LinkedBlockingQueue,允许请求队列无限增长,可能导致OOM(内存溢出)

newCachedThreadPool和newScheduledThreadPool,允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量线程,导致系统资源耗尽

2、无法精细控制

工厂方法使用了预设的参数,无法根据实际业务场景进行精细调整,隐藏了线程池的实际运行机制,开发人员难以意识到潜在风险。

二、案例1:电商系统中的订单处理服务OOM问题

在电商系统的秒杀活动中,订单处理服务使用Executors.newFixedThreadPool(10)创建线程池,当遇到大量请求时,任务队列无限增长导致内存溢出。

newFixedThreadPool内部使用LinkedBlockingQueue没有设置容量上限,请求堆积时内存会持续增长。

// 问题代码
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 大量提交任务
for (Order order : orders) {
    executorService.submit(() -> processOrder(order));
}

使用ThreadPoolExecutor手动创建线程池,并设置合理的队列大小和拒绝策略。

// 优化后的代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                       // 核心线程数
    10,                      // 最大线程数
    60L, TimeUnit.SECONDS,   // 线程空闲超时时间
    new LinkedBlockingQueue<>(1000), // 有界队列,容量为1000
    new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("order-process-thread-" + t.getId());
            return t;
        }
    },
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程执行
);

// 提交任务
for (Order order : orders) {
    executor.submit(() -> processOrder(order));
}

队列有明确的容量上限防止内存溢出,线程数有明确上限,使用CallerRunsPolicy在系统超负荷时能够自动降速,自定义线程名称便于问题排查。

三、案例2:定时任务系统线程爆炸

企业内部的定时任务系统使用Executors.newCachedThreadPool()处理各类定时任务,随着业务增长,某天系统突然无响应。

// 问题代码
ExecutorService executor = Executors.newCachedThreadPool();
// 定时任务系统中添加各种任务
for (Task task : tasks) {
    executor.submit(() -> executeTask(task));
}

newCachedThreadPool允许创建的最大线程数是Integer.MAX_VALUE,当系统负载较高时,会创建过多线程,导致线程上下文切换开销巨大,最终系统崩溃。

手动创建线程池,限制最大线程数,并增加监控。

// 优化后的代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10,                      // 核心线程数
    50,                      // 最大线程数(明确上限)
    3, TimeUnit.MINUTES,     // 非核心线程存活时间
    new ArrayBlockingQueue<>(2000), // 有界队列
    new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("scheduled-task-" + t.getId());
            t.setDaemon(true); // 设置为守护线程
            return t;
        }
    },
    new ThreadPoolExecutor.AbortPolicy() // 任务拒绝时抛出异常,便于及时发现问题
);

// 添加监控
executor.setRejectedExecutionHandler((r, e) -> {
    log.error("任务队列已满,任务被拒绝执行");
    // 触发告警通知
    alertService.sendAlert("线程池队列已满,请检查系统负载!");
    throw new RejectedExecutionException("线程池任务队列已满");
});

// 提交任务
for (Task task : tasks) {
    executor.submit(() -> executeTask(task));
}

明确限制最大线程数防止线程爆炸,避免过多的线程上下文切换,异常情况下能够快速发现并告警,队列和线程数都有明确上限。

在这里插入图片描述

四、手动创建线程池的好处

1、资源可控性更强

明确指定线程数上限和任务队列容量,避免资源耗尽。防止OOM(内存溢出)和线程爆炸问题,系统资源使用更加可预测和稳定。

2、业务适配性更好

根据业务特点精确调整参数,为IO密集型任务设置较高的线程数,为CPU密集型任务设置相对较少的线程数,可以针对不同业务场景设计不同参数配置的线程池。

3、异常处理更加优雅

自定义拒绝策略,系统超负荷时可以优雅降级,可以选择合适的策略:调用者运行、丢弃任务、丢弃最老任务或抛出异常,甚至可以实现自定义的复杂拒绝处理逻辑,如将任务存入数据库等。

4、监控能力更强

添加自定义监控和告警逻辑,可以实时监控线程池状态,如活跃线程数、队列深度等,在异常情况下及时触发告警,避免系统崩溃。

5、问题排查更便捷

通过自定义ThreadFactory给线程池中的线程合理命名,便于在日志和线程转储中快速定位问题,可以添加额外的线程元数据,如来源业务、优先级等。

五、总结

《阿里巴巴Java开发手册》禁止使用Executors创建线程池的规定并非过度谨慎,而是基于大量生产实践经验总结出的宝贵教训。通过手动创建ThreadPoolExecutor,我们能够明确控制线程数量上限和任务队列容量,有效防止资源耗尽导致的系统崩溃。

在高并发场景下,线程池配置不当引发的问题往往具有突发性和灾难性,可能在系统长期稳定运行后的某个峰值时刻突然爆发。正确的做法是遵循"自定义线程池参数、限制资源上限、设置拒绝策略、加强监控告警"的原则,根据业务特性精细调整线程池配置。

六、国内直接使用最新GPT-4.5、满血ChatGPT4o、o1、o3-mini-high、Claude 3.7 Sonnet、满血DeepSeek R1、Grok 3

✅️谷歌浏览器直接访问

Claude使用地址:https://claude.nezhagpt.cloud

在这里插入图片描述

✅️ChatGPT使用地址:www.nezhasoft.cloud

在这里插入图片描述

1、纯原版ChatGPT、Claude

✅️官网原生页面

✅️真实Team会员账号

2、技术支持

✔️支持最新ChatGPT-4.5、满血ChatGPT-4o、o1、o3-mini、o3-mini-high、o1 pro

✔️Claude 3.7 Sonnent

✔️满血DeepSeek R1、马斯克Grok 3

✔️无需魔法、个人独享

3、支持所有GPTs + 自定义插件

支持ChatGPT所有插件,可创建自己的ChatGPT插件,使用朋友分享的自定义插件。

例如最强编程插件Code Copilot、AI绘画插件DALL-E、论文专属Consensus。

在这里插入图片描述

为何阿里代码规约要求手动创建线程池,我的踩坑和升级 前言 很久没有写点东西了,主要是工作不忙,所忙的工作也都是比较简单的,并未遇到我没有接触过的技术,之前一直有一个需求就是对字段加密,而需要加密的字段有311万多,最初都是用单线程去写的,一次查询2000条,然后加密后一条一条的更新,结果一算,311万得花费5.7个小时,太慢了,于是就看了同事之前写的多线程,拷贝过来发现我的阿里编码规约提示:手动创建线程池,效果会更好哦 解决过程 参考博客 我之前通篇看过阿里编码规约,这块说到了我才有印象。晚上查了一下,参考了这几篇博客 1、阿里不推荐使用Executors创 阅读详情

相关推荐

为什么阿里不建议用excutors创建线程池

1 前言: 大家都知道,阿里规范中有一条是不允许用excutors去创建线程池,而是采用ThreadPoolExecutor的原生方式去创建。很早就听过所过这种说法,但是一直都没去搞清楚是为什么,今天就查阅资料去了解了这个问题。 2 Excutors创建线程的方式 通过Excutors来创建线程池,有4种创建线程的方法。 newCachedThreadPool创建一个可缓存线程池,如果线程池的大小超过了处理任务所需的线程,那么就会回收部份空闲线(60秒不处理任务)线程...

爪哇人的博客 3006

【Java】阿里规范-线程池创建

核心线程:必须大于0,一直存在的线程,不会被关闭最大线程:一般设置大于或者等于核心线程,不能小于核心线程,最大线程数=核心线程数+普通线程数,普通线程数在等待时间满后会自动关闭,节省开销处理时间:每个线程处理任务的最大时间,普通线程超过该时间会shutDown时间单位:处理时间的单位,一般设置为秒阻塞队列:选择缓存队列的方式,未处理的任务会在阻塞队列里面等待线程执行线程:使用线程工程创建线程,可以命名,方便运行区分线程属于哪个线程池的。

风浪很小 2211

Java高并发编程实战14,强制禁止,线程池不允许使用Executors创建

大家好,我是哪吒。在程序开发中,高并发场景越来越多,线程池首当其冲。简单回顾一下:《阿里巴巴 Java 开发手册》强制禁止,线程池不允许使用Executors创建,而是通过ThreadPoolExecutor的方式创建,这样的处理方式能让编写代码的工程师更加明确线程池的运行规则,避免资源耗尽的风险。Executors返回的线程池对象的弊端如下:好吧,昨天,我还通过创建了一个线程池,看来以后要注意了。具体分析以下【说明】中的内容,以FixedThreadPool为例,允许的请求队列长度为Integer.MAX

学Java,找哪吒 1759

Java线程池—附阿里巴巴Java开发手册强制规范要求

线程池就是一个可以复用线程的技术。想象一下,如果不使用线程池会有什么问题?假设:用户每次发起一个请求给后台,后台就创建一个新的线程来处理,下次新的任务过来肯定也会创建新的线程,如果用户量非常大,创建的线程也讲越来越多。然而,创建线程是开销很大的,并且请求过多时,会严重影响系统性能。而使用线程池,就可以解决上面的问题。如下图所示,线程池内部会有一个容器,存储几个核心线程,假设有3个核心线程,这3个核心线程可以处理3个任务。

qq_45858191的博客 2792

揭秘个人开发者接支付宝的‘野路子’:不用企业资质,用Python模拟扫码转账与回调监听

本文探讨了个人开发者如何通过Python模拟支付宝扫码转账与回调监听的技术实现,解析了支付宝URL协议格式,并设计了本地化的支付状态监听方案。文章强调该方法仅用于技术研究,实际应用需遵守支付宝官方接口和金融合规要求。

weixin_30736301的博客 408

Abaqus中Cohesive单元建模:从本构到失效的完整指南

本文提供了Abaqus中Cohesive单元建模的完整指南,涵盖从本构模型到失效分析的全过程。详细解析了Cohesive单元作为模拟界面粘结与失效的关键工具,其核心在于弹性本构、损伤起始准则和损伤演化定律的设置。文章通过双悬臂梁(DCB)实例,手把手指导前处理、材料定义、求解设置及后处理分析,并分享了刚度、强度、断裂能等关键参数的影响与收敛性调优的实用避坑技巧,帮助用户准确模拟复合材料及胶接结构的界面失效行为。

cuda7parallel的博客 700

面试官:为什么《阿里巴巴Java开发手册》上要禁止使用Executors来创建线程池

面试官:为什么《阿里巴巴Java开发手册》上要禁止使用Executors来创建线程池

天堂的博客 3078

Hypermesh联合ABAQUS—Sets的建立和编辑

打开part copy对话框在对话框的最上面位置可以输入copy后的名称,然后将最下面的Separate disconnected regions into parts(将不连续的区域分割成parts)选项的前面方框勾选上。打开abaqus软件界面,File→import→model,将file filter选为inp格式,找到要导入的有限元文件,单击OK导入文件。HyperWorks新建Set时,会在Model Browser显示,打开Create Set对话框显示详细信息。快捷键,高亮set的内容。

动力资料屋的博客 1290

为什么《阿里巴巴Java开发手册》禁止使用Executors创建线程池?

作为CEO,你很快发现,这些预设的团队(Executors工厂方法)虽然方便,但都有“无限”的风险(无限的订单货架或无限的兼职人员)。一个成熟的CEO(专业的开发者),会选择亲自定制团队(直接使用构造函数),他会明确规定:•核心员工有几位?•最多能招多少兼职?• 兼职人员闲置多久就辞退?•“待处理”的货架最大能放多少订单?workQueue• 订单彻底爆仓了怎么办?这才是对公司(系统)资源最负责、最安全的方式。线程池种类核心比喻正式工团队众包兼职平台王牌专送员定时/周期配送团队核心线程。

郑龙飞 1371

Fluent基于低氧舱气体交换仿真(氮气与空气混合)

一、背景概述 模拟低氧舱充氮气和排除混合气体的过程,假设注入95%的氮气,舱内原有气体为空气,压力为标准大气压,温度为300K。观察气体注入过程中,舱内平均氮气和氧气浓度的变化。 二、Fluent设置 Setup 1、General type选择压力基 绝对速度 瞬态 重力勾选 2、Model 能量方程开启 组分运输开启,设置方法如下: 选择后OK,view就会变成Edit,点击Edit。然后再次点击Edit。 将组分中的非氮气氧气和空气的气体移除,右边选项需要将空气放在最后一位。 3、Materi

qq_35535616的博客 1万+

STM32G431的 FDCAN使用5M加速时,出现奇葩问题,如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1635

阿里巴巴Java开发手册明确禁止使用Executors来创建线程池,你还在用吗

前言 我们知道,即使是在单线程模式下,我们也要尽量使用Executor。即: //创建固定线程池,然而阿里手册明文禁止Executors创建线程池 private static ExecutorService fixThreadPool = Executors.newFixedThreadPool(1); 阿里手册明文禁止Executors创建线程池,如下 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更

weixin_39098944的博客 1028

【ACP】2025-最新-疑难题解析- 练习二汇总

全球加速是优化公网访问的,负载均衡是分发流量的,公网 NAT 网关是处理公网 IP 的,高速通道是建私网连接但不直接提供固定私网地址功能。C 是客户端加密方式,D 是 ECS 云盘加密,都不属于 OSS 服务器端加密。某企业想使用云服务器 ECS + 负载均衡 SLB + 弹性伸缩 (Auto Scaling) 的架构搭建一个企业级门户网站,技术负责人对于负载均衡和弹性伸缩配合使用没有经验,于是将他理解的两种产品配合使用的一些技术细节列成了一个表单,并请作为架构师的您帮他做一下鉴别,以下哪些项是正确的?

jundao1997的专栏 293

线程池七个参数与阿里巴巴开发手册

什么是线程池 在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。 线程池:Java中开辟出了一种管理线程的概念,这个概念叫做线程池,从概念以及应用场景中,我们可以看出,线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。 如何创建线程池 可以通过ExecutorService创建 public class ThreadDemo { public static v

yiqqYi的博客 526

关务管理项目专题:SAP 与关衡关务系统的进出口报关业务集成(1)需求和方案整理

一个拥有进出口业务的企业就需要报关,而关务系统就是用来辅助企业日常进出口报关,同时数字化、合规化报关业务的有效工具。本章属于关务管理项目专题系列,以 SAP 与关衡关务系统的进出口报关业务集成为实例,详细讲解报关业务的需求和方案整理。

SAP李斌,本人承诺所有原创文章均不使用任何AI生成技术,请大家放心阅读。 2075

【重识云原生】第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现

vDPA(vhost Data Path Acceleration)即是让virtio数据平面不需主机干预的解决方案。该框架由Redhat提出,实现了virtio数据平面的硬件卸载。控制平面仍然采用原来的控制平面协议,当控制信息被传递到硬件中,硬件完成数据平面的配置之后,数据通信过程由硬件设备(智能网卡)完成,虚拟机与网卡之间直通。中断信息也由网卡直接发送至虚拟机不需要主机的干预。......

junbaozi的专栏 2188

项目使用线程池_60%的Java程序员在错误的使用线程池,如何正确创建线程池

前言阿里的Java开发者手册中对于线程池的创建有很多强制性的限制,其中最重要的一条就是: 线程池不允许使用Executors去创建,那我们改如何正确的使用Java线程池技术呢?Java线程池使用场景Java线程池技术是我们经常会用到的一项技术,例如定时任务、异步数据处理、队列等我们都会用到线程池技术。Java的JUC包有很多API可以让我们创建一个线程池,那这些API我们改如何正确使用呢?为什么在...

weixin_42659791的博客 120

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

21java-多线程-高级

从newFixedThreadPool的底层来看,LinkedBlockingQueue是一个用链表实现的有界阻塞队列,它并未指定容量,是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE.对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况就有可能因为任务过多导致内存溢出问题。​ 线程池在启动的时,会创建大量空闲线程,当我们向线程池提交任务的时,线程池就会启动一个线程来执行该任务。核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。

qq_71116105的博客 1088

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

阿里巴巴Java开发手册重点解读(一)

编程规约-OOP规约-8【强制】关于基本数据类型与包装数据类型的使用标准如下: 1) 所有的 POJO 类属性必须使用包装数据类型。 2) RPC 方法的返回值和参数必须使用包装数据类型。 3) 所有的局部变量【推荐】 使用基本数据类型。 这些类型的对象常作为查询对象或者结果对象,基本数据类型的默认值都是0,而引用类型的默认值为null。在拼接sql时或者显示结果时,null有明确的含义,

小9的专栏 2354

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

java json删除指定元素_这才是阿里巴巴Java开发手册的正确打开姿势

作者 l Hollis来源 l Hollis(ID:hollischuang)原文链接: http://mp.weixin.qq.com/s?__biz=Mzg3MjA4MTExMw==&mid=2247487438&idx=2&sn=e74c1b62660cddc5b791914996024202很多人都知道,阿里巴巴在2017发布了《阿里巴巴Java开发手册》,前后推出...

weixin_39556891的博客 221

线程池基础

文章目录 前言 一、线程池简介 二、Executors工具类 三、线程池参数 四、线程池工作原理 五、BlockingQueue 六、拒绝策略 七、线程池关闭 八、相关问题 总结 前言 本篇主要是自己对线程池基础的总结。 一、线程池简介 1. 线程池作用 1.1.降低资源消耗,通过重复利用已创建的线程降低线程创建、销毁造成的消耗; 1.2.提高响应速度,当任务到达时,可以不需要等待线程创建就能立即执行; 1.3.提高线程的可管理性。 2. 线程池组成 2.1.线程池管理器(Thread

u010006156的博客 198

阿里巴巴开发规范——不允许使用Executors来创建线程池

阿里巴巴Java开发手册中明确指出,而且用的词是『不允许』使用Executors创建线程池: 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式, 这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors各个方法的弊端: 1)newFixedThreadPool和newSingleThreadExec...

_夜渐凉 1万+

线程池创建陷阱:为什么阿里禁止使用Executors?

Executors 的工厂方法虽然方便,但隐藏了线程池的核心参数和配置,容易导致资源耗尽、拒绝策略不灵活、难以监控和调优等问题。相比之下,直接使用 ThreadPoolExecutor 构造函数创建线程池,可以更精细地控制线程池的行为,更好地适应实际业务需求。

xujunson的博客 1125

为什么阿里巴巴禁止使用 Executors 创建线程池?

阿里巴巴开发手册为什么禁止使用Executors去创建线程池,原因就是和两个方法允许请求的最大队列长度是,可能会出现任务堆积,出现OOM。允许创建的线程数量为,可能会创建大量的线程,导致发生OOM。它建议使用方式去创建线程池,通过上面的分析我们也知道了其实Executors三种创建线程池的方式最终就是通过来创建的,只不过有些参数我们无法控制,如果通过的构造器去创建,我们就可以根据实际需求控制线程池需要的任何参数,避免发生OOM异常。为什么阿里巴巴禁止使用 Executors 创建线程池?-优快云博客。

qq_63882368的博客 466
上一篇: 华为OD机试 - 查找接口成功率最优时间段 - 回溯(Python/JS/C/C++ 2025 C卷 100分)
下一篇: 华为OD机试题库清单以及考点说明,2025.3.16切换2025A卷
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2933原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值