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

网站做子页面怎么做的网站seo具体怎么做

网站做子页面怎么做的,网站seo具体怎么做,东莞营销专业网站建设,深圳住房和建设局网站预约在日常开发中#xff0c;我们经常会用到时间#xff0c;我们有很多办法在Java代码中获取时间。但是不同的方法获取到的时间的格式都不尽相同#xff0c;这时候就需要一种格式化工具#xff0c;把时间显示成我们需要的格式。 最常用的方法就是使用SimpleDateFormat类。这是一…在日常开发中我们经常会用到时间我们有很多办法在Java代码中获取时间。但是不同的方法获取到的时间的格式都不尽相同这时候就需要一种格式化工具把时间显示成我们需要的格式。 最常用的方法就是使用SimpleDateFormat类。这是一个看上去功能比较简单的类但是一旦使用不当也有可能导致很大的问题。 在阿里巴巴Java开发手册中有如下明确规定 那么本文就围绕SimpleDateFormat的用法、原理等来深入分析下如何以正确的姿势使用它。 SimpleDateFormat用法 SimpleDateFormat是Java提供的一个格式化和解析日期的工具类。它允许进行格式化日期 - 文本、解析文本 - 日期和规范化。SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。 在Java中可以使用SimpleDateFormat的format方法将一个Date类型转化成String类型并且可以指定输出格式。 // Date转String Date data new Date(); SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss); String dataStr sdf.format(data); System.out.println(dataStr); 复制代码 以上代码转换的结果是2018-11-25 13:00:00日期和时间格式由日期和时间模式字符串指定。如果你想要转换成其他格式只要指定不同的时间模式就行了。 在Java中可以使用SimpleDateFormat的parse方法将一个String类型转化成Date类型。 // String转Data System.out.println(sdf.parse(dataStr)); 复制代码 日期和时间模式表达方法 在使用SimpleDateFormat的时候需要通过字母来描述时间元素并组装成想要的日期和时间模式。常用的时间元素和字母的对应表如下 模式字母通常是重复的其数量确定其精确表示。如下表是常用的输出格式的表示方法。 输出不同时区的时间 时区是地球上的区域使用同一个时间定义。以前人们通过观察太阳的位置时角决定时间这就使得不同经度的地方的时间有所不同地方时。1863年首次使用时区的概念。时区通过设立一个区域的标准时间部分地解决了这个问题。 世界各个国家位于地球不同位置上因此不同国家特别是东西跨度大的国家日出、日落时间必定有所偏差。这些偏差就是所谓的时差。 现今全球共分为24个时区。由于实用上常常1个国家或1个省份同时跨着2个或更多时区为了照顾到行政上的方便常将1个国家或1个省份划在一起。所以时区并不严格按南北直线来划分而是按自然条件来划分。例如中国幅员宽广差不多跨5个时区但为了使用方便简单实际上在只用东八时区的标准时即北京时间为准。 由于不同的时区的时间是不一样的甚至同一个国家的不同城市时间都可能不一样所以在Java中想要获取时间的时候要重点关注一下时区问题。 默认情况下如果不指明在创建日期的时候会使用当前计算机所在的时区作为默认时区这也是为什么我们通过只要使用new Date()就可以获取中国的当前时间的原因。 那么如何在Java代码中获取不同时区的时间呢SimpleDateFormat可以实现这个功能。 SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss); sdf.setTimeZone(TimeZone.getTimeZone(America/Los_Angeles)); System.out.println(sdf.format(Calendar.getInstance().getTime())); 复制代码 以上代码转换的结果是 2018-11-24 21:00:00 。既中国的时间是11月25日的13点而美国洛杉矶时间比中国北京时间慢了16个小时这还和冬夏令时有关系就不详细展开了。 如果你感兴趣你还可以尝试打印一下美国纽约时间America/New_York。纽约时间是2018-11-25 00:00:00。纽约时间比中国北京时间早了13个小时。 当然这不是显示其他时区的唯一方法不过本文主要为了介绍SimpleDateFormat其他方法暂不介绍了。 SimpleDateFormat线程安全性 由于SimpleDateFormat比较常用而且在一般情况下一个应用中的时间显示模式都是一样的所以很多人愿意使用如下方式定义SimpleDateFormat public class Main {private static SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);public static void main(String[] args) {simpleDateFormat.setTimeZone(TimeZone.getTimeZone(America/New_York));System.out.println(simpleDateFormat.format(Calendar.getInstance().getTime()));} } 复制代码 这种定义方式存在很大的安全隐患。 问题重现 我们来看一段代码以下代码使用线程池来执行时间输出。 /** * author Hollis */ public class Main {/*** 定义一个全局的SimpleDateFormat*/private static SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);/*** 使用ThreadFactoryBuilder定义一个线程池*/private static ThreadFactory namedThreadFactory new ThreadFactoryBuilder().setNameFormat(demo-pool-%d).build();private static ExecutorService pool new ThreadPoolExecutor(5, 200,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());/*** 定义一个CountDownLatch保证所有子线程执行完之后主线程再执行*/private static CountDownLatch countDownLatch new CountDownLatch(100);public static void main(String[] args) {//定义一个线程安全的HashSetSetString dates Collections.synchronizedSet(new HashSetString());for (int i 0; i 100; i) {//获取当前时间Calendar calendar Calendar.getInstance();int finalI i;pool.execute(() - {//时间增加calendar.add(Calendar.DATE, finalI);//通过simpleDateFormat把时间转换成字符串String dateString simpleDateFormat.format(calendar.getTime());//把字符串放入Set中dates.add(dateString);//countDowncountDownLatch.countDown();});}//阻塞直到countDown数量为0countDownLatch.await();//输出去重后的时间个数System.out.println(dates.size());} } 复制代码 以上代码其实比较简单很容易理解。就是循环一百次每次循环的时候都在当前时间基础上增加一个天数这个天数随着循环次数而变化然后把所有日期放入一个线程安全的、带有去重功能的Set中然后输出Set中元素个数。 上面的例子我特意写的稍微复杂了一些不过我几乎都加了注释。这里面涉及到了线程池的创建、CountDownLatch、lambda表达式、线程安全的HashSet等知识。感兴趣的朋友可以逐一了解一下。 正常情况下以上代码输出结果应该是100。但是实际执行结果是一个小于100的数字。 原因就是因为SimpleDateFormat作为一个非线程安全的类被当做了共享变量在多个线程中进行使用这就出现了线程安全问题。 在阿里巴巴Java开发手册的第一章第六节——并发处理中关于这一点也有明确说明 那么接下来我们就来看下到底是为什么以及该如何解决。 线程不安全原因 通过以上代码我们发现了在并发场景中使用SimpleDateFormat会有线程安全问题。其实JDK文档中已经明确表明了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. 那么接下来分析下为什么会出现这种问题SimpleDateFormat底层到底是怎么实现的 我们跟一下SimpleDateFormat类中format方法的实现其实就能发现端倪。 SimpleDateFormat中的format方法在执行过程中会使用一个成员变量calendar来保存时间。这其实就是问题的关键。 由于我们在声明SimpleDateFormat的时候使用的是static定义的。那么这个SimpleDateFormat就是一个共享变量随之SimpleDateFormat中的calendar也就可以被多个线程访问到。 假设线程1刚刚执行完calendar.setTime把时间设置成2018-11-11还没等执行完线程2又执行了calendar.setTime把时间改成了2018-12-12。这时候线程1继续往下执行拿到的calendar.getTime得到的时间就是线程2改过之后的。 除了format方法以外SimpleDateFormat的parse方法也有同样的问题。 所以不要把SimpleDateFormat作为一个共享变量使用。 如何解决 前面介绍过了SimpleDateFormat存在的问题以及问题存在的原因那么有什么办法解决这种问题呢 解决方法有很多这里介绍三个比较常用的方法。 使用局部变量 for (int i 0; i 100; i) {//获取当前时间Calendar calendar Calendar.getInstance();int finalI i;pool.execute(() - {// SimpleDateFormat声明成局部变量SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);//时间增加calendar.add(Calendar.DATE, finalI);//通过simpleDateFormat把时间转换成字符串String dateString simpleDateFormat.format(calendar.getTime());//把字符串放入Set中dates.add(dateString);//countDowncountDownLatch.countDown();}); } 复制代码 SimpleDateFormat变成了局部变量就不会被多个线程同时访问到了就避免了线程安全问题。 加同步锁 除了改成局部变量以外还有一种方法大家可能比较熟悉的就是对于共享变量进行加锁。 for (int i 0; i 100; i) {//获取当前时间Calendar calendar Calendar.getInstance();int finalI i;pool.execute(() - {//加锁synchronized (simpleDateFormat) {//时间增加calendar.add(Calendar.DATE, finalI);//通过simpleDateFormat把时间转换成字符串String dateString simpleDateFormat.format(calendar.getTime());//把字符串放入Set中dates.add(dateString);//countDowncountDownLatch.countDown();}}); } 复制代码 通过加锁使多个线程排队顺序执行。避免了并发导致的线程安全问题。 其实以上代码还有可以改进的地方就是可以把锁的粒度再设置的小一点可以只对simpleDateFormat.format这一行加锁这样效率更高一些。 使用ThreadLocal 第三种方式就是使用 ThreadLocal。 ThreadLocal 可以确保每个线程都可以得到单独的一个 SimpleDateFormat 的对象那么自然也就不存在竞争问题了。 /*** 使用ThreadLocal定义一个全局的SimpleDateFormat*/ private static ThreadLocalSimpleDateFormat simpleDateFormatThreadLocal new ThreadLocalSimpleDateFormat() {Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);} };//用法 String dateString simpleDateFormatThreadLocal.get().format(calendar.getTime()); 复制代码 用 ThreadLocal 来实现其实是有点类似于缓存的思路每个线程都有一个独享的对象避免了频繁创建对象也避免了多线程的竞争。 当然以上代码也有改进空间就是其实SimpleDateFormat的创建过程可以改为延迟加载。这里就不详细介绍了。 使用DateTimeFormatter 如果是Java8应用可以使用DateTimeFormatter代替SimpleDateFormat这是一个线程安全的格式化工具类。就像官方文档中说的这个类 simple beautiful strong immutable thread-safe。 //解析日期 String dateStr 2016年10月25日; DateTimeFormatter formatter DateTimeFormatter.ofPattern(yyyy年MM月dd日); LocalDate date LocalDate.parse(dateStr, formatter);//日期转换为字符串 LocalDateTime now LocalDateTime.now(); DateTimeFormatter format DateTimeFormatter.ofPattern(yyyy年MM月dd日 hh:mm a); String nowStr now .format(format); System.out.println(nowStr); 复制代码 总结 本文介绍了SimpleDateFormat的用法SimpleDateFormat主要可以在String和Date之间做转换还可以将时间转换成不同时区输出。同时提到在并发场景中SimpleDateFormat是不能保证线程安全的需要开发者自己来保证其安全性。 主要的几个手段有改为局部变量、使用synchronized加锁、使用Threadlocal为每一个线程单独创建一个等。 希望通过此文你可以在使用SimpleDateFormat的时候更加得心应手。
http://www.pierceye.com/news/280383/

相关文章:

  • 钢管公司网站建设国外平面设计欣赏网站
  • 网站建设如何销售济南专门做网站的公司
  • 2018年淘宝客网站怎么做iis网站建设中
  • 网站倒计时代码企业网站建设运营方案
  • 课程网站开发过程东莞外贸模板建站
  • asp.net 网站提速廊坊企业官网搭建
  • 网站开发全过程电商数据分析
  • 代理 指定网站 hostwordpress图片无限放大
  • 中材建设有限公司招标网站包装设计网课答案
  • python云服务器网站开发实例外贸小家电网站推广
  • 郑州做网站公司中天猫商城的商品来源
  • 织梦网站首页互联网保险平台排名
  • 免费做链接的网站做动画相册在哪个网站好
  • 做思维导图好看的网站可以做富集分析的网站
  • wordpress 媒体库 cos百度网站怎样优化排名
  • 自助建站程序html样式模板
  • 公主岭网站建设筑梦网站建设
  • 昊源建设监理有限公司网站广州住房与城乡建设部网站
  • 如何免费建立自己网站wordpress媒体优化
  • 南京企业做网站网站建设的类型有几种
  • 不需要证件做网站相城区建设网站
  • 游戏推广网站如何做的全网投放广告的渠道有哪些
  • 飞数石家庄网站建设seo 关键词优化
  • 织梦新手网站建设建筑工程公司资质
  • 网站建设开什么名目外贸网站建设关键点
  • 大学生网站设计河南省建筑工程信息网
  • 安徽省住房和城乡建设厅网站首页wordpress评论框中加文字提示
  • 南京营销型网站建设公司杭州模板建站代理
  • 网页设计比较优秀的网站沈阳网站推广公司
  • 西安网站建设维护如何免费制作app软件