从一条阿里编码规范谈线程池的使用

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

最近在看阿里Java编程规范,有一条引起了我的注意:

【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:

  1. FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
  2. CachedThreadPool 和ScheduledThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

平时没怎么注意这一点,一般用的多的还是FixedThreadPool 和 SingleThreadPool。那怎么理解这条规范呢?首先,ThreadPoolExecutor是更底层的类,直接用它的构造方法,可以让我们对创建的线程池有更强的控制。

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), handler);
}

我们来看下ThreadPoolExecutor的参数设定:

  • corePoolSize:核心线程数(就算有空闲线程,也不会低于这个数)
  • maximumPoolSize:最大线程数
  • keepAliveTime:最大存活时间(超过corePoolSize数量的线程空闲下最大存活时间)
  • unit:时间单位
  • workQueue:工作队列(核心线程满后,任务会进入这里)
  • handler:任务满负荷(超出最大线程数和工作队列上限之和)后的处理策略

其中处理策略有四种:

  • AbortPolicy:默认策略,在需要拒绝任务时抛出RejectedExecutionException
  • CallerRunsPolicy:直接在 execute 方法的调用线程中运行被拒绝的任务,如果线程池已经关闭,任务将被丢弃
  • DiscardPolicy:直接丢弃任务
  • DiscardOldestPolicy:丢弃队列中等待时间最长的任务,并执行当前提交的任务,如果线程池已经关闭,任务将被丢弃

除此之外我们也可以自定义处理策略。

作为对比,我们看下FixedThreadPool的实现:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

可见它实际上就是个简化版的ThreadPoolExecutor,通过固定线程数,然后指定工作队列长度为无限(不传长度代表容量无限)。这样确实可能会造成任务无限堆积,引起OOM的问题。所以阿里的规范建议我们直接使用更底层的ThreadPoolExecutor,把处理策略之类的都提前设定好。

不过规范也不是死的,在实际情况中也无法避免使用FixedThreadPool等更高层的实现。一方面是因为使用起来更加方便,另一方面也是有时候使用ThreadPoolExecutor并没有明显的好处。例如:线程池中分配的任务都是关键任务,无法被丢弃,然后因为性能考虑也无法被execute线程同步执行,这样就很难定义一个合适的处理策略,不如直接使用FixedThreadPool。就算有OOM的风险,那也只能说在多种风险权衡下做的一个评估和取舍。

阿里巴巴编码规范 考题分析 http://www.doc88.com/p-3126470726938.html https://blog.youkuaiyun.com/QYHuiiQ/article/details/85916287 https://www.e-learn.cn/content/java/1154711 https://hacpai.com/article/1542680916301 https://segmen... 阅读详情

相关推荐

ThreadsPoolBuilder工具类

阿里的代码规范中提出,不推荐使用JDK提供的线程池创建方法(newCachedThreadPool、newFixedThreadPool等),因此对ThreadsPoolExecutor方法进行了简单封装,以方便使用。

阿里巴巴Java开发规范线程池_线程池 -- 推荐线程池 ThreadPoolExecutor

ThreadPoolExecutor是阿里巴巴 JAVA 编码规范里面推荐的使用线程池的正确姿势它提供了四个构造方法:我们以最后一个构造方法(参数最多的那个),对其参数进行解释:public ThreadPoolExecutor(int corePoolSize, // 1int maximumPoolSize, // 2long keepAliveTime, // 3TimeUnit uni...

weixin_39849239的博客 1624

技术文档的语言表达:简洁、准确与易懂的平衡艺术

技术文档的语言表达不仅要简洁、准确,还需要能够打破技术壁垒,使不同背景的读者都能理解。这是一项需要技巧和经验的工作,它要求技术作者既要具备扎实的专业知识,又要具备清晰的表达能力。通过不断打磨语言的简洁性、准确性和易懂性,我们能够创造出一份高质量的技术文档,让知识的传递不再受限于语言的障碍。

人心有反复,好在山水有重逢。 4677

java并发编程 - Exexctors 工具类

Executors 类提供了一系列静态工厂方法用于创建各种线程池。 newFixedThreadPool 创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 如果线程池中的所有线程都处于活动状态,此时再提交任务就在队列中等待,直到有可用线程。 newS...

weixin_30642561的博客 259

如何在项目中集成bpmn-process-designer

文章目录一、bpmn-process-designer是什么?二、使用步骤1.将下面地址的代码下载到本地2.替换dependencies和devDependencies3.拷贝package目录4.在main.js引入代码5.拷贝src5.拷贝App.vue代码注意事项 一、bpmn-process-designer是什么? bpmn-process-designer是一个基于 bpmn.js,Vue 2.x 和 ElementUI 开发的流程设计器(前端部分),支持监听器,扩展属性,表单等配置,可自由扩展

weixin_43550766的博客 9454

libero烧录信号抓取

提示:如果改了东西需要重新烧录,需要把这两个界面都关闭再libero打开。两个红色的要关闭掉。然后返回libero开始烧录,观测信号(如果只烧录观测从这一步开始就行)等到下面的messige出现以下信息表示run好了。在下图中右侧可以自己设置,设置完之后记得保存一下。run一下,耐心等待,有警告就ok,run完之后。run成功会变绿色,然后点下面的这个看波形。设置抓取信号:在libero打开。打开的就是烧录界面,直接run。

qq_34047965的博客 1422

Java 线程池的基本介绍和使用

在 Java 中,可以利用线程做很多事情,创建多个线程来高效的完成任务,例如 Tomcat 用多个线程来接收和处理请求,我们也可以创建多个线程来批量处理数据,原本串行执行的任务变成并行执行,充分利用 CPU 多个核的性能。这样子确实能够并发完成任务,但是也带了问题:创建的线程数量不可控制,一个任务就创建一个线程,当任务量庞大的时候,会带来极大的,反复创建、销毁线程。⭐ 在实际开发中,如果需要创建超过五个线程执行类似的任务,就可以考虑使用线程池了。

2301_76607156的博客 295

麒麟V10系统下微信PC版安装全攻略:从源配置到一键安装(附常见问题解决)

本文详细介绍了在麒麟V10系统下安装和优化微信PC版的完整流程,包括系统环境准备、软件源配置、多途径安装方案以及性能优化技巧。特别针对国产操作系统用户,提供了从基础安装到高级配置的一站式解决方案,并附有常见问题排查方法,帮助用户快速实现微信PC版的高效运行。

weixin_30500105的博客 717

【阿里开发规范】ThreadPoolExecutor自定义线程池示例(亲测)

【阿里开发规范】ThreadPoolExecutor自定义线程池示例(亲测)

zss123yq的博客 6538

利用ArcGIS创建渔网计算渔网内土地利用占比划分中国北方农牧交错带

依据土地利用数据,根据参考文献划分要求,利用ArcGIS创建渔网对地物进行重分类,划分农业带、牧业带以及农牧交错带。

m0_60672527的博客 3059

告别I2C和SPI:用FPGA驱动DS18B20,一根线搞定温度采集(附Verilog代码)

本文详细介绍了如何利用FPGA通过单总线协议(One-Wire)驱动DS18B20温度传感器,仅用一根数据线实现高效温度采集。内容涵盖协议解析、Verilog代码实现及调试技巧,帮助开发者节省IO资源并提升系统性能。

weixin_42696271的博客 389

Java开发经验——阿里巴巴编码规范实践解析9

这篇文章主要介绍了阿里巴巴Java开发中关于远程调用超时设置、线程池隔离、服务器性能优化等编码规范的实践解析。强调了超时设置的重要性,提供了多种技术栈的超时设置示例。同时,探讨了高并发服务器的TCP协议time_wait超时时间调优、最大文件句柄数调整、JVM参数优化等实践。还涉及了线程池隔离的必要性及实现方式,以及服务器重定向的规范和线程池管理的解决方案。

庄小焱 1119

ceph recovery 相关参数

可以修改的最大回填/恢复选项列在 “恢复/回填选项” 部分。mClock 的修改 默认回填/恢复限制由 osd_mclock_override_recovery_settings 选项,设置为 默认为 false。尝试修改任何默认恢复/回填限制而不设置门控选项,会将该选项重置为 mClock 默认值,并在集群日志中记录一条警告消息。请注意,默认值可能需要几秒钟才能恢复生效。请使用 config show 命令验证限制,如下所示。就直接设置以下参数,过一会就变回了默认值。简单点说官网的意思就是不设置。

weixin_40548182的博客 279

线程池超级详解 吐血整理

线程池 详解 吐血整理 数哥:你们用多线程吗? 我:用啊 数哥:我们根本不需要,厉害吧 我:。。。。。。厉害 数哥:你们怎么用的啊? 我:一般都是用线程池,不会直接创建线程 数哥:线程池??? 干什么的? 我:。。。。。。 !!!!!! 1、使用线程池的好处 我们知道创建 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下 2、线程池创建、执行 2.1线程池的执行流程

beauty-coding 的博客 6665

qt医疗信息系统(HIS)

**UI 组件**: QWidget、QTextBrowser、QTableWidget、QGraphicsView 等。- **网络通信**: Qt Network (TCP/IP)- **DICOM 处理**: DCMTK 3.6.7。- **数据库**: SQLite (轻量、跨平台)**数据库文件**: `hospital.db`- **开发框架**: Qt 6 (C++)- 医疗影像 (DICOM) 查看器。**医疗影像 (DICOM) 查看器****电子病历 (EMR) 浏览器**

寒寒豆豆软件公司的博客 338

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

阿里巴巴编码规范考试答案

1.如何处理单元测试产生的数据,下列哪些说法是正确的?【ABC 】多选 A .测试数据入库时加特殊前缀标识。 B .测试数据使用独立的测试库。 C .自动回滚单元测试产生的脏数据。 D .无须区别,统一在业务代码中进行判断和识别。 2.关于并发处理,下列哪些说法符合《阿里巴巴Java开发手册》:【ABC】多选 A .线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。 B .同步处理时,能锁部分代码区块的情况下不要锁整个方法;高并发时,同步调用...

qq_58003121的博客 1万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

阿里规范 不要显式创建线程,请使用线程池以及手动创建线程池,效果会更好哦

idea阿里规范 不要显式创建线程,请使用线程池以及手动创建线程池,效果会更好哦的处理

qq_45235979的博客 5668

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

阿里编码规范重点内容讲解

阿里编码规范重点内容讲解 一、编码风格: 1.命名风格 驼峰命名法 不能以下划线或美元符号开始,也不能以下划线或美元符号结束 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类 命名以它要测试的类名开始,以 Test 结尾。 类型与中括号紧挨相连来定义数组。 public static ...

qq_38475119的博客 1267

如何在项目中优雅使用线程池,你学废了么?

fixedThreadPool.submit(() -> System.out.println("异步任务"));这种线程池的使用方式,每次方法调用的时候,需要初始化线程池,使用完线程之后的shutdown。Executors工具类中提供了几种初始化线程池的方式。阿里编码规范中建议,不要用Executors来创建线程池,可能有OOM风险,具体原因可以参见阿里军规--禁用Executors创建线程池。这里可以使用ThreadPoolExecutor来创建线程池。

爱琴孩的博客 2262

java 全局线程池_java 线程池(线程的复用)

一. 线程池简介1. 线程池的概念:线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。2. 线程池的工作机制2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某...

weixin_36221082的博客 3146

使用线程池工具类创建线程执行任务

文章目录工具类简单使用 单个任务查询3秒,3个任务顺序执行9秒。 如果用线程池创建三个线程同时执行三个任务,耗时基本上也在3秒。 线程的好处可见一斑。 创建线程,按照阿里巴巴开发规范,建议我们 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程 —————————————————————————————— 原因: 使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资 源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者 “过度切换”的问题。

Luoposhan_master的博客 745

阿里Java编码规范笔记

对于DO/BO/DTO/VO/AO/PO的类命名时,使用UserDO,MoveDTO命名 POJO类中布尔类型的变量不要加is前缀 Long类型初始赋值时使用大写L 注释的双斜线与内容之间1个空格 // 注释内容 单行字符不超过120个,超出换行缩进一个tab,且第三行起不再缩进 方法覆盖时,必须加@Override注解 方法过时时必须加@Deprecated注释,并清晰说明采用的新接口 使用"test".equals(str) 而不是 str.equals(“tes..

GYongJia的博客 303

JDK Executors 线程池 分析

ThreadPoolExecutor 源码分析—— https://www.jianshu.com/p/03ba5c4dabbe 阿里java编码规范: 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样 的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors 返回的线程...

weixin_42226343的博客 230

分享一款非常强大的动态线程池

;分享好玩的项目,挖掘开源的价值。;大家好,我是【开源君】。今天给大家分享的开源项目的是【dynamic-threadpool】

weixin_44028058的博客 910

如何快速掌握P3C:阿里巴巴Java编码规范的完整实施指南

在Java开发的世界中,代码质量直接关系到项目的可维护性、团队协作效率和最终产品的稳定性。阿里巴巴Java编码规范插件(P3C)正是为了解决这一问题而诞生的强大工具。本文将为您提供从零开始掌握P3C的完整指南,帮助您和团队快速提升代码质量。 ## 为什么每个Java开发者都需要P3C?🚀 P3C是阿里巴巴技术团队多年实战经验的结晶,它将复杂的编码规范转化为自动化的检查工具,让代码质量保障变得

gitblog_00129的博客 366

阿里编码规范

编程规约 命名风格 代码命名不能以下划线或者美元符号开头或者结尾 代码命名不能以中文拼音或者中文拼音与英文混合方式 类名使用UpperCamCamelCase风格,但DO、PO、DTO、VO、BO等除外 方法名、参数名、变量名统一使用lowerCamelCase,必须遵守驼峰命名 常量名全部大写,单词间用下划线隔开 抽象类必须以Abstract或者Base开头,异常类必须以Exception结尾,测试 类以测试的类的名称开头Test结尾 类型与中括号紧挨相连标示数组 POJO类中布尔类型变量不要加is前缀

优快云JAVALIKE的博客 4725
上一篇: 记一次服务端定时器问题的解决
下一篇: 如何有效阅读一本技术书
长三月
博客等级 码龄9年 228粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值