一个简单的Java对象池实现——可用来解决SimpleDateFormat的线程安全问题

Java工具类设计规范与鸿蒙适配实战 工具类(Utility Class)是Java开发中的基础组件,通过封装通用操作提升代码复用率。其核心设计原则包括无状态性、不可变性和功能内聚,采用final类+私有构造器确保线程安全。在性能优化方面,可采用对象池化技术和避免自动装箱等方案。随着鸿蒙OS等分布式系统的普及,工具类需要特别关注跨平台兼容性,可通过抽象工厂模式实现Android与鸿蒙的能力映射。良好的工具类设计能显著提升代码质量,尤其在百万级用户APP中,规范的参数校验和防御性编程能有效避免内存泄漏和线程安全问题。 阅读详情

被SimpleDateFormat的线程安全问题困扰过的人应该不止我一个吧。为了解决这个类的线程安全问题,通常我们会有以下两种做法:

  1. 每次都new 一个SimpleDateFormat对象,但频繁的创建与销毁对象带来的性能问题……哈哈,我就不在这里过多的BB了。
  2. 使用ThreadLocal技术,这恐怕是最常用的一种解决方案,我想几乎每个有经验的Java程序员都使用过它,在此我也不多说啦,如果真有不知到的,且看下面这篇博文:
    SimpleDateFormat的线程安全问题与解决方案

然而,最近在调试过程中意外进入了 XStream这个类库, XStream是一个可以将javaBean与XML双向转换的java类库,本文内容基于xstream-1.4.9版本。所需maven依赖如下:

<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.9</version>
</dependency>

不过,本文不是讲解这个类库是如何使用的,而是想说,我在这个类库中发现了一种新颖的可以避免SimpleDateFormat线程安全问题的实现:也即采用对象池,让不同的线程可以使用对象池中不同的SimpleDateFormat对象,并且保证在同一时刻池中的任一对象只能被一条线程使用,从而避免线程安全。

当然XStream中的对象池的实现及其简单,只有简单的借出对象和归还对象,所以完善程度远远无法和apache common pool这种通用且成熟的对象池实现相比(进一个类,数行代码)。不过对于帮助我没理解对象池如何实现到是大有用处。由于实现简单,我就不多解释了,直接贴代码吧。

对象池的简单java实现如下(出自XStream库)

public class Pool {

    public interface Factory {
        public Object newInstance();
    }

    private final int initialPoolSize;
    private final int maxPoolSize;
    private final Factory factory;
    private transient Object[] pool;
    private transient int nextAvailable;
    private transient Object mutex = new Object();

    public Pool(int initialPoolSize, int maxPoolSize, Factory factory) {
        this.initialPoolSize = initialPoolSize;
        this.maxPoolSize = maxPoolSize;
        this.factory = factory;
    }

    public Object fetchFromPool() {
        Object result;
        synchronized (mutex) {
            if (pool == null) {
                pool = new Object[maxPoolSize];
                for (nextAvailable = initialPoolSize; nextAvailable > 0; ) {
                    putInPool(factory.newInstance());
                }
            }
            while (nextAvailable == maxPoolSize) {
                try {
                    mutex.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException("Interrupted whilst waiting " +
                            "for a free item in the pool : " + e.getMessage());
                }
            }
            result = pool[nextAvailable++];
            if (result == null) {
                result = factory.newInstance();
                putInPool(result);
                ++nextAvailable;
            }
        }
        return result;
    }

    protected void putInPool(Object object) {
        synchronized (mutex) {
            pool[--nextAvailable] = object;
            mutex.notify();
        }
    }

    private Object readResolve() {
        mutex = new Object();
        return this;
    }
}

线程安全的SimpleDateFormat的实现如下(同样出自XStream包):

public class ThreadSafeSimpleDateFormat {

    private final String formatString;
    private final Pool pool;

    public ThreadSafeSimpleDateFormat(String format, int initialPoolSize, int maxPoolSize, final boolean lenient) {
        formatString = format;
        pool = new Pool(initialPoolSize, maxPoolSize, new Pool.Factory() {
            public Object newInstance() {
                SimpleDateFormat dateFormat = new SimpleDateFormat(formatString, Locale.ENGLISH);
                dateFormat.setLenient(lenient);
                return dateFormat;
            }

        });
    }

    public String format(Date date) {
        DateFormat format = fetchFromPool();
        try {
            return format.format(date);
        } finally {
            pool.putInPool(format);
        }
    }

    public Date parse(String date) throws ParseException {
        DateFormat format = fetchFromPool();
        try {
            return format.parse(date);
        } finally {
            pool.putInPool(format);
        }
    }

    private DateFormat fetchFromPool() {
        TimeZone tz = TimeZone.getDefault();
        DateFormat format = (DateFormat)pool.fetchFromPool();
        if (!tz.equals(format.getTimeZone())) {
            format.setTimeZone(tz);
        }
        return format;
    }
}
科研作图不发愁:手把手教你用PyMOL给蛋白-DNA互作图‘美颜’(附完整配色与标注方案) 本文详细介绍了如何使用PyMOL对蛋白-DNA互作结构图进行专业美化,包括从PDB文件加载、结构展示与标注、互作位点突出显示到高质量渲染输出的完整流程。通过具体案例(PDB ID:8SSS)演示了锌指结构域区分、关键残基标注和互作距离测量等实用技巧,帮助科研人员制作可直接用于期刊投稿的高质量示意图。 阅读详情

相关推荐

visual studio 2017编译Triangle库遇到的问题和解决办法

这段时间因为一个项目需要使用到Triangle这个三角剖分工具,需要在windows环境下进行对源码编译,中间踩了很多坑,特此记录下。 1、下载 下载链接是下边这个,需要翻墙 http://www.cs.cmu.edu/~quake/triangle.html 2、编译。。超。。。级。。。麻。。。烦。。。 在ubutu下安装一切顺利,完全没遇到什么麻烦,但是换到windows下就麻烦不断...

csubai07的博客 2438

SimpleDateFormat线程不安全解析以及解决方案

在下面的代码中我们定义了SimpleDateFormat对象被使用的总次数以及同时使用的最大线程的数量。这个establish方法接收了一个参数calendar,而这个对象是一个SimpleDateFormat对象的遍历,多线程使用同一个这个对象,而在这个。是Java中用来日期格式化的一个类,可以将特定格式的字符转转化成日期,也可将日期转化成特定格式的字符串。对象内部的数据在多线程的操作下混乱了,也就导致在进行数据格式化的时候出现了原本不应该出现的数字,也就导致了。对象就会出现安全问题。

怕什么真理无穷,进一寸有一寸的欢喜。即使开了一辆老掉牙的破车,只要在前行就好,偶尔吹点小风,这就是幸 532

无人驾驶小车调试笔记(六)-- 车轮校准

简介:小车的动力完全来自于两个电机带动的车轮,在理想状态下,给两个电机同样的驱动参数,两个车轮会以同样的转速带动小车直线行驶,而实际情况是每个电机可能都会有个体差异,也就是说给予同样的驱动参数,表现出的转动速度会有些许不同,两个轮子的差速会导致车辆拐弯,后果就是给了直线行驶的控制命令,但是车走着走着就偏离了原本的方向,所以在开始控制之前,我们需要先平衡两个车轮的转速,保证在同样驱动参数下,两个车轮转速大致相同,也就是可以走直线。 车轮校准分为3步,测试、调整后再测试、保存参...

aibingjin的博客 1820

simpledateformat 线程安全问题及其优化方案

转载 simpledateformat非线程安全问题 ...

肥肥的博客 776

第069篇:浸入边界法进阶

浸入边界法(Immersed Boundary Method, IBM)是处理流固耦合问题的强大数值方法。本文深入介绍直接力法、反馈力法、Ghost Cell方法和多域IBM等高级技术。通过Python实现完整的IBM求解器,展示处理移动边界、弹性边界和多体相互作用的方法。浸入边界法,直接力法,反馈力法,Ghost Cell,流固耦合,移动边界,弹性边界Navier-Stokes方程添加体积力项:∂u∂t+(u⋅∇)u=−1ρ∇p+ν∇2u+f\frac{\partial \mathbf{u}}{\part

2401_87715305的博客 412

YOLO11实战优化:长尾分布解决 | 引入Seesaw Loss配合YOLO11分类头,完美应对类别极其不平衡的现实业务场景

摘要: YOLO11在工业缺陷检测等长尾分布场景中面临尾部类别检测失效的问题,根源在于头部类别样本的负样本梯度压制了尾部类别的学习。传统方法如重采样、Focal Loss等效果有限。Seesaw Loss通过动态调整缓解因子和补偿因子,平衡类别间的梯度分布,结合YOLO11的解耦分类头、Anchor-Free设计和C2PSA/C3K2模块,显著提升尾部类别识别能力。文章详细解析了Seesaw Loss的数学原理,并提供了可直接集成到YOLO11的PyTorch实现代码,为长尾分布下的目标检测提供了实用解决方

2601_95807009的博客 252

java设计模式学习之【对象池模式】

这篇教程不仅提供了对象池模式的理论基础,还通过具体的Java代码示例展示了如何实现和应用这种模式。简单理解,通俗易懂

qq_33129875的博客 2577

Yolov8轻量级网络:Ghostnet、G_ghost、Ghostnetv2家族大作战(一):华为Ghostnet,超越谷歌MobileNet | CVPR2020

Yolov8引入轻量级网络Ghostnet、G_ghost、Ghostnetv2等,减少最新的深度神经网络的计算成本,引入高效的神经网络结构。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 2567

Java 中的对象池实现

最近在分析一个应用中的某个接口的耗时情况时,发现一个看起来极其普通的对象创建操作,竟然每次需要消耗 8ms 左右时间,分析后发现这个对象可以通过对象池模式进行优化,优化后此步耗时仅有 0.01ms。...

未读代码 3612

【网络与爬虫 53】Scrapy-Prometheus实战指南:打造企业级爬虫监控体系的终极解决方案

本文深入探讨Scrapy-Prometheus集成技术,通过费曼学习法从监控痛点出发,详细讲解如何在Scrapy爬虫中集成Prometheus指标收集系统。涵盖从基础配置到企业级监控体系的完整实战指南,帮助开发者构建可观测性强、可维护性高的分布式爬虫监控平台,实现爬虫性能的精准监控和智能告警。

熵数实验室 1584

【Bluedroid】AVRCP 连接源码分析(一)

AVRCP连接源码分析流程是一个涉及多个步骤和协议交互的复杂过程。在源码中,需要仔细处理各种连接状态和协议交互,以确保AVRCP连接的稳定性和可靠性。同时,还需要根据具体的应用场景和需求,对AVRCP命令和响应进行定制化处理。

byte轻骑兵的技术小窝 3315

高并发之——SimpleDateFormat类的线程安全问题和解决方案

首先问下大家:你使用的SimpleDateFormat类还安全吗?带着这个问题再来看本文。 提起SimpleDateFormat类,想必做过Java开发的童鞋都不会感到陌生。没错,它就是Java中提供的日期时间的转化类。这里,为什么说SimpleDateFormat类有线程安全问题呢?有些小伙伴可能会提出疑问:我们生产环境上一直在使用SimpleDateFormat类来解析和格式化日期和时间类型...

冰河的专栏 1万+

(五)激光线扫描-位移台标定

线激光属于主动测量方式,但是由于线激光的特性,我们只能通过提取激光中心线获取这一条线上的高度信息,那么要进行三维重建的话,就需要通过平移或者是旋转的方式,来让线激光扫描被测物体的完整轮廓,也就是整个表面。激光线的密度越高还原出来的物体越细腻,但由于数据量大,也会导致速度变慢。下面以位移台为例讲解,如何标定位移台。

FlyWine的博客 2889

对象池化工具commons-pool

关于对象池的概念这里不做过多解释,除了用来缓存数据库连接java.sql.Connection这种重量级对象也适用于其他场景。   以SimpleDateFormat 为例,这是 Java 中非常常用的一个类,用于解析和格式化日期字符串。   但是 SimpleDateFormat 在多线程环境中并不是线程安全的。详见这位仁兄的 SimpleDateFormat 的线程安全问题与 ThreadL

家山的专栏 885

OV9734 DATASHEET,完整规格书

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

深度学习工具包 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")

java线程不安全类 SimpleDateFormat

不安全在什么地方? 前段时间在做系统数据清洗过程中,因为用到多线程及simpeldateformat,一开始没注意,遇到了线程安全问题,就在此描述解决办法。 // Called from Format after creating a FieldDelegate private StringBuffer format(Date date, StringBuffer toAppend

山月记 676

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

生产级Java代码:线程安全、死锁预防与内存管理实战

在多线程编程中,线程安全和死锁预防是保证系统稳定性的核心技术。通过合理使用不可变对象、显式锁和线程局部存储,可以有效解决共享状态访问问题。死锁预防则需结合锁排序、超时机制等工程实践,而内存管理则需要关注对象池化、流式处理等优化手段。这些技术在高并发交易系统、金融支付等7×24小时运行场景中尤为重要。本文基于金融系统实战经验,详细解析如何通过三层防御体系实现线程安全,以及如何通过锁优化和内存监控构建可靠的生产级代码。

adr5970的博客 442

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java并发编程 - 共享模型之不可变

如果一个对象在不能够修改其内部状态(属性),那么它就是线程安全的,因为不存在并发修改啊!

OneFine的技术博客 473

ObjectMapper性能优化:避免频繁创建的四种方案

在Java开发中,JSON序列化与反序列化是高频操作,Jackson的ObjectMapper作为核心处理工具,其线程安全特性允许实例复用。从技术原理看,每次创建ObjectMapper都会触发元数据加载、模块注册等耗时操作,实测显示单次创建需要50-100ms。通过静态单例、Spring托管等方案复用实例,不仅能提升90%以上的处理性能(如基准测试中单线程从12ops/ms提升至158ops/ms),还能避免内存激增和配置不一致问题。这类优化在微服务、API网关等高并发场景尤为重要,结合对象池或Threa

weixin_30814329的博客 456

Java对象缓存池

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33690367的博客 359

使用pool2编写时间格式枚举辅助类

一个比较纠结的问题,SimpleDateFormat这个类是线程不安全的,在多线程的并发下极其容易出现问题,每次使用的时候都要新建一个对象太消耗资源。这段时间正好在使用REDIS,REDIS底层是使用的pool2来实现的,所以考虑使用pool2对SimpleDateFormat做一个缓存池,代码如下。 package tests.pool2; import java.text.SimpleDa

莫看烟雨的专栏 408

并发编程——6.共享模型之不可变

共享模型之不可变

代码星辰的博客 1042

java对象缓存_Java对象缓存池 - Acce1erator的个人空间 - OSCHINA - 中文开源技术交流社区...

package common;import java.util.Arrays;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;public abstract class AbstractObjectPool {private Map> pool;private volatile int maxSize;pu...

weixin_33785971的博客 223

Java 并发编程笔记 第七章:共享模型_不可变

网课链接: 黑马程序员java并发. 第七章:共享模型 不可变第七章 共享模型_不可变章节总结7.1 日期转换的问题同步锁不可变对象7.2 不可变设计final的使用final 原理设置final变量的原理保护性拷贝 defensive copy享元模式 flyweight pattern体现包装类String 串池BigInteger BigDecimalDIY - 数据库连接池7.3 无状态 第七章 共享模型_不可变 章节总结 不可变类型使用 不可变类设计 原理 final 模式方面 享元模式

weixin_41225956的博客 248

Java基础类库

Java基础类库 一、Java常用类库 1、StringBuffer String类是在所有项目开发之中一定会使用到的一个功能类,并且这个类拥有如下的特点: 每一个字符串的常量都属于一个String类的匿名对象,并且不可更改 String有两个常量池:静态常量池、运行时常量池 String类对象实例化建议使用直接赋值的形式完成,这样可以直接将对象保存在对象池之中以方便下次重用 String类最大的弊端:内容不允许修改。虽然大部分情况下都不会设计到字符串的内容的频繁修改,但是依然可能存在有着样的情况,所以

qq_50743381的博客 1094

剑指JUC原理-11.不可变设计

定义英文名称:Flyweight pattern. 当需要重用数量有限的同一类对象时(每次保护性拷贝都需要创建新的字符串,如果有取值相同的对象已经有了,那就可以重用这些对象,而不是每次都创建新的)

爱吃知识的土豆倪的博客 365

学习Aandroid开发第一天-java基础(part2数组、String、Date)

数组 数组指的就是一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作 数组初始化方式 1)动态初始化方式一:int data[] = new int[3] 2)动态初始化方式二,分布式数组空间开辟: int data[] = null; data = new int[3] 3)静态初始化:int data[] = {1, 2, 4, 545, 11, 32, 13131, 4444};...

积极面对生活,快乐学习 315
上一篇: 字符串搜索算法Boyer-Moore的Java实现
下一篇: 恢复centos7与windows7系统引导方法-亲测可用
lhever_
博客等级 码龄14年 213粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值