当前位置: 首页 > news >正文

如何编辑网站源代码为什么网站建设还要续费

如何编辑网站源代码,为什么网站建设还要续费,关键词的选取原则,网页设计模板html免费一、前言 日期的转换与格式化在项目中应该是比较常用的了 一个问题#xff1a;项目中的日期转换怎么用的#xff1f;SimpleDateFormat 用过吗#xff1f;能说一下 SimpleDateFormat 线程安全问题吗#xff0c;以及如何解决#xff1f; 回答#xff1a;平时就是在全局定…一、前言 日期的转换与格式化在项目中应该是比较常用的了 一个问题项目中的日期转换怎么用的SimpleDateFormat 用过吗能说一下 SimpleDateFormat 线程安全问题吗以及如何解决 回答平时就是在全局定义一个 static的 SimpleDateFormat然后在业务处理方法controller中直接使用至于线程安全… 这个… 倒是没遇到过线程安全问题。 下面讲解一下。 二、概述 SimpleDateFormat 类主要负责日期的转换与格式化等操作在多线程的环境中使用此类容易造成数据转换及处理的不正确因为 SimpleDateFormat 类并不是线程安全的但在单线程环境下是没有问题的。 SimpleDateFormat 在类注释中也提醒大家不适用于多线程场景 Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.日期格式不同步。 建议为每个线程创建单独的格式实例。 如果多个线程同时访问一种格式则必须在外部同步该格式。来看看阿里巴巴 java 开发规范是怎么描述 SimpleDateFormat 的 三、模拟线程安全问题 无码无真相接下来我们创建一个线程来模拟 SimpleDateFormat 线程安全问题 创建 MyThread.java 类 public class MyThread extends Thread{private SimpleDateFormat simpleDateFormat;/* 要转换的日期字符串 */private String dateString;public MyThread(SimpleDateFormat simpleDateFormat, String dateString){this.simpleDateFormat simpleDateFormat;this.dateString dateString;}Overridepublic void run() {try {Date date simpleDateFormat.parse(dateString);String newDate simpleDateFormat.format(date).toString();if(!newDate.equals(dateString)){System.out.println(ThreadName this.getName() 报错了日期字符串 dateString 转换成的日期为 newDate);}}catch (ParseException e){e.printStackTrace();}} }创建执行类 Test.java 类 public class Test {// 一般我们使用SimpleDateFormat的时候会把它定义为一个静态变量避免频繁创建它的对象实例private static SimpleDateFormat simpleDateFormat new SimpleDateFormat(YYYY-MM-dd);public static void main(String[] args) {String[] dateStringArray new String[] { 2020-09-10, 2020-09-11, 2020-09-12, 2020-09-13, 2020-09-14};MyThread[] myThreads new MyThread[5];// 创建线程for (int i 0; i 5; i) {myThreads[i] new MyThread(simpleDateFormat, dateStringArray[i]);}// 启动线程for (int i 0; i 5; i) {myThreads[i].start();}} }执行截图如下 从控制台打印的结果来看使用单例的 SimpleDateFormat 类在多线程的环境中处理日期转换极易出现转换异常java.lang.NumberFormatException:multiple points以及转换错误的情况。 四、线程不安全的原因 这个时候就需要看看源码了format() 格式转换方法 // 成员变量 Calendar protected Calendar calendar;private StringBuffer format(Date date, StringBuffer toAppendTo,FieldDelegate delegate) {// Convert input date to time field listcalendar.setTime(date);boolean useDateFormatSymbols useDateFormatSymbols();for (int i 0; i compiledPattern.length; ) {int tag compiledPattern[i] 8;int count compiledPattern[i] 0xff;if (count 255) {count compiledPattern[i] 16;count | compiledPattern[i];}switch (tag) {case TAG_QUOTE_ASCII_CHAR:toAppendTo.append((char)count);break;case TAG_QUOTE_CHARS:toAppendTo.append(compiledPattern, i, count);i count;break;default:subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);break;}}return toAppendTo; }我们把重点放在 calendar 这个 format 方法在执行过程中会操作成员变量 calendar 来保存时间 calendar.setTime(date) 。 但由于在声明 SimpleDateFormat 的时候使用的是 static 定义的那么这个 SimpleDateFormat 就是一个共享变量SimpleDateFormat 中的 calendar 也就可以被多个线程访问到所以问题就出现了举个例子 假设线程 A 刚执行完 calendar.setTime(date) 语句把时间设置为 2020-09-01但线程还没执行完线程 B 又执行了 calendar.setTime(date) 语句把时间设置为 2020-09-02这个时候就出现幻读了线程 A 继续执行下去的时候拿到的 calendar.getTime 得到的时间就是线程B改过之后的。 除了 format() 方法以外SimpleDateFormat 的 parse 方法也有同样的问题。 至此我们发现了 SimpleDateFormat 的弊端所以为了解决这个问题就是不要把 SimpleDateFormat 当做一个共享变量来使用。 五、如何解决线程安全 1、每次使用就创建一个新的 SimpleDateFormat 创建全局工具类 DateUtils.java public class DateUtils {public static Date parse(String formatPattern, String dateString) throws ParseException {return new SimpleDateFormat(formatPattern).parse(dateString);}public static String format(String formatPattern, Date date){return new SimpleDateFormat(formatPattern).format(date);} }所有用到 SimpleDateFormat 的地方全部用 DateUtils 替换然后看一下执行结果 好家伙异常错误终于是没了这种解决处理错误的原理就是创建了多个 SimpleDateFormat 类的实例在需要用到的地方创建一个新的实例就没有线程安全问题不过也加重了创建对象的负担会频繁地创建和销毁对象效率较低。 2、synchronized 锁 synchronized 就不展开介绍了 变更一下 DateUtils.java public class DateUtils {private static final SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);public static Date parse(String formatPattern, String dateString) throws ParseException {synchronized (simpleDateFormat){return simpleDateFormat.parse(dateString);}}public static String format(String formatPattern, Date date) {synchronized (simpleDateFormat){return simpleDateFormat.format(date);}} }简单粗暴synchronized 往上一套也可以解决线程安全问题缺点自然就是并发量大的时候会对性能有影响因为使用了 synchronized 加锁后的多线程就相当于串行线程阻塞执行效率低。 3、ThreadLocal最佳MVP ThreadLocal 是 java 里一种特殊的变量ThreadLocal 提供了线程本地的实例它与普通变量的区别在于每个使用该线程变量的线程都会初始化一个完全独立的实例副本。 继续改造 DateUtils.java public class DateUtils {private static ThreadLocalDateFormat threadLocal new ThreadLocalDateFormat(){Overrideprotected DateFormat initialValue() {return new SimpleDateFormat(yyyy-MM-dd);}};public static Date parse(String formatPattern, String dateString) throws ParseException {return threadLocal.get().parse(dateString);}public static String format(String formatPattern, Date date) {return threadLocal.get().format(date);} }ThreadLocal 可以确保每个线程都可以得到单独的一个 SimpleDateFormat 的对象那么就不会存在竞争问题。 如果项目中还在使用 SimpleDateFormat 的话推荐这种写法但这样就结束了吗 显然不是… 六、项目中推荐的写法 上边提到的阿里巴巴 java 开发手册给出了说明如果是 JDK8 的应用可以使用 Instant 代替 DateLocalDateTime 代替 CalendarDateTimeFormatter 代替 SimpleDateFormat官方给出的解释simple beautiful strong immutable thread-safe。 日期转换SimpleDateFormat 固然好用但是现在我们已经有了更好地选择Java 8 引入了新的日期时间 API并引入了线程安全的日期类一起来看看。 Instant瞬时实例。LocalDate本地日期不包含具体时间 例如2014-01-14 可以用来记录生日、纪念日、加盟日等。LocalTime本地时间不包含日期。LocalDateTime组合了日期和时间但不包含时差和时区信息。ZonedDateTime最完整的日期时间包含时区和相对UTC或格林威治的时差。 新API还引入了 ZoneOffSet 和 ZoneId 类使得解决时区问题更为简便。 解析、格式化时间的 DateTimeFormatter 类也进行了全部重新设计。 例如我们使用 LocalDate 代替 Date使用 DateTimeFormatter 代替 SimpleDateFormat如下所示: // 当前日期和时间 String DateNow LocalDateTime.now().format(DateTimeFormatter.ofPattern(yyyy/MM/dd HH:mm:ss)); System.out.println(DateNow);这样就避免了 SimpleDateFormat 的线程不安全问题啦。 此时的 DateUtils.java public class DateUtils {public static final DateTimeFormatter DATE_TIME_FORMATTER DateTimeFormatter.ofPattern(yyyy-MM-dd);public static LocalDate parse(String dateString){return LocalDate.parse(dateString, DATE_TIME_FORMATTER);}public static String format(LocalDate target) {return target.format(DATE_TIME_FORMATTER);} }七、最后总结 SimpleDateFormart 线程不安全问题SimpleDateFormart 继承自 DateFormart在 DataFormat 类内部有一个 Calendar 对象引用SimpleDateFormat 转换日期都是靠这个 Calendar 对象来操作的比如 parse(String)format(date) 等类似的方法Calendar 在用的时候是直接使用的而且是改变了 Calendar 的值这样情况在多线程下就会出现线程安全问题如果 SimpleDateFormart 是静态的话那么多个 thread 之间就会共享这个 SimpleDateFormart同时也会共享这个 Calendar 引用那么就出现数据赋值覆盖情况也就是线程安全问题。(现在项目中用到日期转换都是使用的 java 8 中的 LocalDate或者 LocalDateTime本质是这些类是不可变类不可变一定程度上保证了线程安全)。 解决方式在多线程下可以使用 ThreadLocal 修饰 SimpleDateFormartThreadLocal 可以确保每个线程都可以得到单独的一个 SimpleDateFormat 的对象那么就不会存在竞争问题。 项目中推荐的写法java 8 中引入新的日期类 API这些类是不可变的且线程安全的。
http://www.zqtcl.cn/news/819565/

相关文章:

  • wordpress构建自己的网站大连网站建设主页
  • 棋牌网站开发工程师网站app制作费用单
  • 为什么做网站比app便宜精准营销服务
  • 网站平台做捐助功能有风险吗wordpress博客 翻墙
  • 泰州网站建设专业团队长沙seo顾问
  • 网站建设情况简介seo的基本步骤顺序正确的是
  • wordpress 文件目录结构关键字优化价格
  • 连云港网站关键字优化市场网站 设计 文档
  • 哈尔滨企业建站服务商龙岩建筑网
  • 四川住房城乡建设厅官方网站中国建设银行在网站怎么签约
  • wordpress tortuga安徽seo网站
  • 厦门商务网站建设网络规划与设计实用教程
  • win8风格门户网站已经建网站做外贸
  • 自己有域名如何做网站wordpress文章中外链
  • 网站模糊背景加快网站速度吗
  • 网站设计软件下载在线观看免费网站网址
  • 关于网站开发的文章wordpress+直接连接数据库
  • 清华紫光网站建设怎样做团购网站
  • 诸城网站建设费用网站建设便捷
  • 丰台网站建设联系方式全屋定制十大名牌口碑
  • mip网站模板中国建设集团门户网站
  • 笑话 语录用什么网站做搜一搜百度
  • 合肥网站建设新闻营销影视类网站建设
  • 焦作有网站建设公司c 转网站开发
  • 化妆品网站建设报告邯郸在哪个省
  • 自建网站怎么做后台管理系统世界网站流量排名
  • 我做外贸要开国际网站吗官方网站下载微博
  • 佛山专业建设网站网页模板是什么
  • 网站描述标签怎么写wordpress首页图标
  • 做系统去哪个网站好好玩又不用实名认证的游戏