iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >java中SimpleDateFormat非线程安全问题的示例分析
  • 502
分享到

java中SimpleDateFormat非线程安全问题的示例分析

2023-06-20 13:06:37 502人浏览 泡泡鱼
摘要

小编给大家分享一下java中SimpleDateFORMat非线程安全问题的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!SimpleDateFormat非线程安全问题实现1000个线程的时间格式化package&

小编给大家分享一下java中SimpleDateFORMat非线程安全问题的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

    SimpleDateFormat非线程安全问题

    实现1000个线程的时间格式化

    package SimpleDateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class SimpleDateFormat1 {    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");    public static void main(String[] args) {        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,10,100,                TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(1000),new ThreadPoolExecutor.DiscardPolicy());        for (int i = 0; i < 1001; i++) {            int finalI = i;            threadPoolExecutor.submit(new Runnable() {                @Override                public void run() {                    Date date = new Date(finalI * 1000);                    myFormatTime(date);                }            });        }        threadPoolExecutor.shutdown();    }    private static void myFormatTime(Date date){        System.out.println(simpleDateFormat.format(date));    }}

    产生了线程不安全的问题?:

    java中SimpleDateFormat非线程安全问题的示例分析

    这是因为:

    java中SimpleDateFormat非线程安全问题的示例分析

    多线程的情况下:

    java中SimpleDateFormat非线程安全问题的示例分析

    线程1在时间片用完之后,线程2来setTime()那么线程1的得到了线程2的时间。

    所以可以使用加的操作:

    java中SimpleDateFormat非线程安全问题的示例分析

    就不会有重复的时间了

    java中SimpleDateFormat非线程安全问题的示例分析

    但是虽然可以解决线程不安全的问题,但是排队等待锁,性能就会变得低

    所以可以使用局部变量:

    java中SimpleDateFormat非线程安全问题的示例分析

    也解决了线程不安全的问题:

    java中SimpleDateFormat非线程安全问题的示例分析

    但是每次也都会创建新的私有变量

    那么有没有一种方案既可以避免加锁排队执行,又不会每次创建任务的时候不会创建私有的变量呢?

    那就是ThreadLocal?:

    ThreadLocal

    ThreadLocal的作用就是让每一个线程都拥有自己的变量。

    那么选择锁还是ThreadLocal?

    看创建实列对象的复用率,如果复用率比较高的话,就使用ThreadLocal。

    ThreadLocal的原理

    类ThreadLocal的主要作用就是将数据放到当前对象的Map中,这个Map时thread类的实列变量。类ThreadLocal自己不管理、不存储任何的数据,它只是数据和Map之间的桥梁。

    执行的流程:数据—>ThreadLocal—>currentThread()—>Map。

    执行后每个Map存有自己的数据,Map中的key中存储的就是ThreadLocal对象,value就是存储的值。每个Thread的Map值只对当前的线程可见,其它的线程不可以访问当前线程对象中Map的值。当前的线程被销毁,Map也随之被销毁,Map中的数据如果没有被引用、没有被使用,则随时GC回收。

    ThreadLocal常用方法

    java中SimpleDateFormat非线程安全问题的示例分析

    set(T):将内容存储到ThreadLocal

    get():从线程去私有的变量

    remove():从线程中移除私有变量

    package ThreadLocalDemo;import java.text.SimpleDateFormat;public class ThreadLocalDemo1 {    private static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<>();    public static void main(String[] args) {        //设置私有变量        threadLocal.set(new SimpleDateFormat("mm:ss"));        //得到ThreadLocal        SimpleDateFormat simpleDateFormat = threadLocal.get();        //移除        threadLocal.remove();    }}

    ThreadLocal的初始化

    ThreadLocal提供了两种初始化的方法

    initialValue()和

    initialValue()初始化:

    package ThreadLocalDemo;import java.text.SimpleDateFormat;import java.util.Date;public class ThreadLocalDemo2 {    //创建并初始化ThreadLocal    private static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal() {        @Override        protected SimpleDateFormat initialValue() {            System.out.println(Thread.currentThread().getName() + "执行了自己的threadLocal中的初始化方法initialValue()");            return new SimpleDateFormat("mm:ss");        }    };    public static void main(String[] args) {        Thread thread1 = new Thread(() -> {            Date date = new Date(5000);            System.out.println("thread0格式化时间之后得结果时:" + threadLocal.get().format(date));        });        thread1.setName("thread0");        thread1.start();        Thread thread2 = new Thread(() -> {            Date date = new Date(6000);            System.out.println("thread1格式化时间之后得结果时:" + threadLocal.get().format(date));        });        thread2.setName("thread1");        thread2.start();    }}

    java中SimpleDateFormat非线程安全问题的示例分析

    withInitial方法初始化:

    package ThreadLocalDemo;import java.util.function.Supplier;public class ThreadLocalDemo3 {    private static ThreadLocal<String> stringThreadLocal =            ThreadLocal.withInitial(new Supplier<String>() {                @Override                public String get() {                    System.out.println("执行了withInitial()方法");                    return "我是" + Thread.currentThread().getName() + "的ThreadLocal";                }            });    public static void main(String[] args) {        Thread thread1 = new Thread(() -> {            System.out.println(stringThreadLocal.get());        });        thread1.start();        Thread thread2 = new Thread(new Runnable() {            @Override            public void run() {                System.out.println(stringThreadLocal.get());            }        });        thread2.start();    }}

    java中SimpleDateFormat非线程安全问题的示例分析

    注意:

    ThreadLocal如果使用了set()方法的话,那么它的初始化方法就不会起作用了。

    来看:?

    package ThreadLocalDemo;class Tools {    public static ThreadLocal t1 = new ThreadLocal();}class ThreadA extends Thread {    @Override    public void run() {        for (int i = 0; i < 10; i++) {            System.out.println("在ThreadA中取值:" + Tools.t1.get());            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}public class ThreadLocalDemo4 {    public static void main(String[] args) throws InterruptedException {        //main是ThreadA 的 父线程 让main线程set,ThreadA,是get不到的        if (Tools.t1.get() == null) {            Tools.t1.set("main父线程的set");        }        System.out.println("main get 到了: " + Tools.t1.get());        Thread.sleep(1000);        ThreadA a = new ThreadA();        a.start();    }}

    java中SimpleDateFormat非线程安全问题的示例分析

    类ThreadLocal不能实现值的继承,那么就可以使用InheritableThreadLocal了?

    InheritableThreadLocal的使用

    使用InheritableThreadLocal可以使子线程继承父线程的值

    java中SimpleDateFormat非线程安全问题的示例分析

    在来看运行的结果:

    java中SimpleDateFormat非线程安全问题的示例分析

    子线程有最新的值,父线程依旧是旧的值

    package ThreadLocalDemo;class ThreadB extends Thread{    @Override    public void run() {        for (int i = 0; i < 10; i++) {            System.out.println("在ThreadB中取值:" + Tools.t1.get());            if (i == 5){                Tools.t1.set("我是ThreadB中新set()");            }            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}public class ThreadLocalDemo5 {    public static void main(String[] args) throws InterruptedException {        if (Tools.t1.get() == null) {            Tools.t1.set("main父线程的set");        }        System.out.println("main get 到了: " + Tools.t1.get());        Thread.sleep(1000);        ThreadA a = new ThreadA();        a.start();        Thread.sleep(5000);        for (int i = 0; i < 10; i++) {            System.out.println("main的get是:" + Tools.t1.get());            Thread.sleep(100);        }    }}

    java中SimpleDateFormat非线程安全问题的示例分析

    ThreadLocal的脏读问题来看?

    package ThreadLocalDemo;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class ThreadLocalDemo6 {    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();    private static class MyThread extends Thread {        private static boolean flag = false;        @Override        public void run() {            String name = this.getName();            if (!flag) {                threadLocal.set(name);                System.out.println(name + "设置了" + name);                flag = true;            }            System.out.println(name + "得到了" + threadLocal.get());        }    }    public static void main(String[] args) {        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0,                TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10));        for (int i = 0; i < 2; i++) {            threadPoolExecutor.execute(new MyThread());        }        threadPoolExecutor.shutdown();    }}

    java中SimpleDateFormat非线程安全问题的示例分析

    发生了脏读:

    线程池复用了线程,也复用了这个线程相关的静态属性,就导致了脏读

    那么如何避免脏读呢?

    去掉static 之后:

    java中SimpleDateFormat非线程安全问题的示例分析

    java中SimpleDateFormat非线程安全问题的示例分析

    看完了这篇文章,相信你对“java中SimpleDateFormat非线程安全问题的示例分析”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

    --结束END--

    本文标题: java中SimpleDateFormat非线程安全问题的示例分析

    本文链接: https://www.lsjlt.com/news/297048.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • java中SimpleDateFormat非线程安全问题的示例分析
      小编给大家分享一下java中SimpleDateFormat非线程安全问题的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!SimpleDateFormat非线程安全问题实现1000个线程的时间格式化package&...
      99+
      2023-06-20
    • Java多线程中线程安全问题的示例分析
      这篇文章主要介绍了Java多线程中线程安全问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 什么是线程安全和线程不安全?什么是线程安全呢?当多个线程并发访问某...
      99+
      2023-06-29
    • java中线程安全问题举例分析
      这篇文章主要讲解了“java中线程安全问题举例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java中线程安全问题举例分析”吧!一、什么时候数据在多线程并发的环境下会存在安全问题?三个条...
      99+
      2023-06-21
    • 如何解决Java中SimpleDateFormat线程不安全的问题
      这篇文章将为大家详细讲解有关如何解决Java中SimpleDateFormat线程不安全的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.什么是线程不安全?线程不安全也叫非线程安全,是指多线程执行中...
      99+
      2023-06-15
    • java中stringbuffer线程安全分析的示例
      这篇文章主要介绍java中stringbuffer线程安全分析的示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了...
      99+
      2023-06-14
    • Java SimpleDateFormat线程不安全问题怎么解决
      本篇内容主要讲解“Java SimpleDateFormat线程不安全问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java SimpleDateFormat线程...
      99+
      2023-07-05
    • SimpleDateFormat线程安全问题排查详解
      目录一. 问题现象二. 原因排查三. 原因分析四. 解决方案一. 问题现象 运营部门反馈使用小程序配置的拉新现金红包活动二维码,在扫码后跳转至404页面。 二. 原因排查 首先,检查...
      99+
      2022-11-13
      SimpleDateFormat线程安全排查 SimpleDateFormat线程安全
    • Java线程安全状态的示例分析
      这篇文章主要为大家展示了“Java线程安全状态的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java线程安全状态的示例分析”这篇文章吧。一、观察线程的所有状态线程的状态是一个枚举类型 ...
      99+
      2023-06-29
    • Java线程之安全与不安全的示例分析
      这篇文章将为大家详细讲解有关Java线程之安全与不安全的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说Stri...
      99+
      2023-05-30
      java
    • Java线程安全与非线程安全解析
      ArrayList和Vector有什么区别?HashMap和HashTable有什么区别?StringBuilder和StringBuffer有什么区别?这些都是Java面试中常见的基础问题。面对这样的问题,回答是:ArrayList是非线...
      99+
      2023-05-31
      java 线程安全 ava
    • python线程安全的示例分析
      这篇文章给大家分享的是有关python线程安全的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。python可以做什么Python是一种编程语言,内置了许多有效的工具,Python几乎无所不能,该语言通俗易...
      99+
      2023-06-14
    • Java多线程同步问题的示例分析
      这篇文章主要介绍Java多线程同步问题的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!简单了解下在操作系统中进程和线程的区别:  进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开...
      99+
      2023-05-30
      java
    • java的SimpleDateFormat线程不安全怎么办
      这篇文章主要为大家展示了“java的SimpleDateFormat线程不安全怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java的SimpleDateFormat线程不安全怎么办”这篇...
      99+
      2023-06-20
    • 详解SimpleDateFormat的线程安全问题与解决方案
      1. 原因SimpleDateFormat(下面简称sdf)类内部有一个Calendar对象引用,它用来储存和这个sdf相关的日期信息,例如sdf.parse(dateStr), sdf.format(date) 诸如此类的方法参数传入的日...
      99+
      2023-05-31
      simpledateformat 线程 dat
    • Java中线程安全问题
      目录一.线程不安全二.那些情况导致了线程不安全?三.Java中解决线程不安全的方案1.volatile“轻量级”解决线程不安全2.synchronized自动加锁四.公平锁与非公平锁...
      99+
      2024-04-02
    • Java单例模式中的线程安全问题
      目录一. 使用多线程需要考虑的因素二. 单例模式1. 饿汉模式2. 懒汉模式3. 懒汉模式(使用synchronized改进)4. 懒汉模式(使用双重校验锁改进)三. volatil...
      99+
      2024-04-02
    • Java中线程的示例分析
      这篇文章主要介绍了Java中线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互...
      99+
      2023-06-25
    • Java线程中的安全策略实例分析
      这篇文章主要介绍“Java线程中的安全策略实例分析”,在日常操作中,相信很多人在Java线程中的安全策略实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java线程中的安全策略实例分析”的疑惑有所帮助!...
      99+
      2023-06-30
    • PHP开发安全问题的示例分析
      PHP开发安全问题的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。对于互联网应用的开发,作为开发者必须时刻牢记安全观念,并在开发的...
      99+
      2024-04-02
    • Java线程安全与不安全实例分析
      本篇内容主要讲解“Java线程安全与不安全实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java线程安全与不安全实例分析”吧!当我们查看JDK API的时候,总会发现一些类说明写着,线程...
      99+
      2023-06-17
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作