• java多线程之不可变final


    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();
            }
        }
    }
    View Code

    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();
            }
        }
    }
    View Code

    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();
            }
        }
    }
    View Code

    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);
        }
    }
    View Code

    完美!

  • 相关阅读:
    vue.js 快速入门
    简洁的MVC思想框架——Nancy(Post操作与外部引用css和JS)
    简洁的MVC思想框架——Nancy(环境配置与Get操作)
    iOS开发之注册推送通知权限
    iOS开发之数组排序
    iOS开发之打包上传报错: ERROR ITMS-90087/ERROR ITMS-90125
    iOS开发之HTTP与HTTPS网络请求
    iOS开发之GCD同步主线程、异步主线程
    iOS开发之获取时间戳方法
    iOS开发之将字典、数组转为JSON字符串方法
  • 原文地址:https://www.cnblogs.com/newAndHui/p/15913642.html
Copyright © 2020-2023  润新知