1.背景

final这个关键字相信大家不陌生吧...

看看下面的案例

2.时间格式化之线程不安全SimpleDateFormat

package com.ldp.demo08final;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat; /**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 02/19 7:37
* @description
*/
@Slf4j
public class Test01SimpleDateFormat {
/**
* 在并发的情况下可能会抛出如下异常:
* Exception in thread "t-3" java.lang.NumberFormatException: For input string: ""
* at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
* at java.lang.Long.parseLong(Long.java:601)
* at java.lang.Long.parseLong(Long.java:631)
* at java.text.DigitList.getLong(DigitList.java:195)
* at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
* at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
* at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
* at java.text.DateFormat.parse(DateFormat.java:364)
* at com.ldp.demo08final.Test01Time.lambda$main$0(Test01Time.java:22)
* at java.lang.Thread.run(Thread.java:748)
*
* @param args
*/
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < 20; i++) {
new Thread(() -> {
try {
log.info("日期为:{}", format.parse("2022-02-02"));
} catch (ParseException e) {
e.printStackTrace();
}
}, "t-" + i).start();
}
}
}

3.时间格式化之加锁实现线程安全

package com.ldp.demo08final;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat; /**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 02/19 7:37
* @description *
* <p>
* 在并发的情况下可能会抛出如下异常:
* Exception in thread "t-3" java.lang.NumberFormatException: For input string: ""
* 解决方案:
* 1.加锁
* 2.不可变的思维
* </p>
*/
@Slf4j
public class Test02SimpleDateFormat {
/**
* 加锁synchronized 的方式解决并发问题
*
* @param args
*/
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < 20; i++) {
new Thread(() -> {
synchronized (format) {
try {
log.info("日期为:{}", format.parse("2022-02-02"));
} catch (ParseException e) {
e.printStackTrace();
}
}
}, "t-" + i).start();
}
}
}

4.时间格式化之DateTimeFormatter线程安全

package com.ldp.demo08final;

import lombok.extern.slf4j.Slf4j;

import java.time.format.DateTimeFormatter;

/**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 02/19 7:49
* @description
*/
@Slf4j
public class Test03DateTimeFormatter {
/**
* 不可变的特性解决并发情况下的线程安全问题
*
* @param args
*/
public static void main(String[] args) {
// @since 1.8
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd");
for (int i = 0; i < 20; i++) {
new Thread(() -> {
try {
log.info("日期为:{}", format.parse("2022-02-02"));
} catch (Exception e) {
e.printStackTrace();
}
}, "t-" + i).start();
}
}
}

5.String对象中使用源码的理解

package com.ldp.demo08final;

import org.junit.Test;

/**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 02/19 7:59
* @description <p>
* 这一节我们来看看String源码
* 1.final 关键字
* 发现String类、类中所有属性多是 final 的
* 属性用 final 修饰保证了该属性是只读的,不能修改
* 类用 final 修饰保证了该类中的方法不能被覆盖,防止子类无意间破坏不可变性
* <p>
* 2.substring方法保护性拷贝
*
* </p>
*/
public class Test04String {
private String name = "final"; /**
* public String substring(int beginIndex) {
* if (beginIndex < 0) {
* throw new StringIndexOutOfBoundsException(beginIndex);
* }
* int subLen = value.length - beginIndex;
* if (subLen < 0) {
* throw new StringIndexOutOfBoundsException(subLen);
* }
* return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
* }
*/
@Test
public void test01Substring() {
String substring = name.substring(2);
System.out.println(substring);
}
}

完美!

java多线程之-不可变final的更多相关文章

  1. Java多线程——不可变对象

    不可变对象条件 对象需要满足一下三个条件才是不可变对象: 1.对象创建以后其状态就不能修改 2.对象所有域都是final类型 3.对象是正确创建的(对象在创建期间,this引用没有溢出) 简而言之就是 ...

  2. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  3. Java多线程开发技巧

    很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...

  4. Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList

    概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析, ...

  5. Java多线程系列--“JUC集合”03之 CopyOnWriteArraySet

    概要 本章是JUC系列中的CopyOnWriteArraySet篇.接下来,会先对CopyOnWriteArraySet进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解 ...

  6. Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  7. Java多线程---同步与锁

    一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...

  8. JAVA 多线程编程之一(基础)

    1.原子变量(java.util.concurrent.atomic) 原子状态,变化不会被打断,如 AtomicLong , AtomicInteger 2.内部锁  synchronized 块 ...

  9. Java多线程编程详解

    转自:http://programming.iteye.com/blog/158568 线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Ja ...

  10. Java 多线程 并发编程

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

随机推荐

  1. work06

    练习题:=============================================================第七题: 1.定义方法 isSXH(int num) 功能:判断数字n ...

  2. vue使用wx-open-launch-weapp

    vue使用wx-open-launch-weapp 官方文档 <template> <div style="width: 100%; height: 100%;" ...

  3. 接口签名规则及Java代码demo实现

    接口签名规则及Java代码demo实现 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用UR ...

  4. Unity下简易字符串指令调试

    Unity下简易字符串指令调试 输入相应的字符串命令即可调用特定的方法,比如让角色等级提升,生成特定数量的Boss等 using System; using UnityEngine; using Sy ...

  5. Mybatis 判断表达式除坑

    Mybatis 判断表达式经常有各种坑,比如数值的判断,空值的判断坑等,可以通过如下代码测试一下是否符合预期 import org.apache.ibatis.ognl.Ognl; import or ...

  6. hbase第一课:hbase-2.2.7分布式搭建

    hbase-2.2.7分布式搭建文档 1.上传解压配置环境变量 # 1.解压 tar -xvf hbase-2.2.7-bin.tar.gz.gz # 2.配置环境变量 vim /etc/profil ...

  7. Android ADB命令集锦

    Android ADB命令集锦 原文(有删改):https://blog.csdn.net/dianziagen/article/details/57400723 本文包括: adb基本指令 Shel ...

  8. ARM Cortex-A系列处理器性能分类比较

    在如今这个电子产品泛滥的年代,仅仅靠品牌或是外观已经不足以辨别产品的优劣,其内置的处理器自然也就成为了分辨产品是否高端的标准之一.那么我们今天就不妨好好了解一下近几年来电子产品中较为主流的RAM处理器 ...

  9. 配置hive环境步骤(zookeeper高可用集群已搭建)

    安装mysql:1. 检查当前环境是否安装mysql服务(命令:rpm -qa | grep -i mysql)2. 卸载自带的mysql3. 卸载软件:rpm -e --nodeps mysql-l ...

  10. Unicode 和JS中的字符串

    计算机内部使用二进制存储数据,只认识0和1两个数字,计算机的世界只有0和1.但我们的世界却充满着文字,如a, b, c.怎样才能让计算机显示文字,供我们使用和交流?只能先把文字转化成数字进行存储,然后 ...