SystemClock.java 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /**
  2. * Copyright (c) 2011-2020, hubin (jobob@qq.com).
  3. * <p>
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. * <p>
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * <p>
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.baomidou.mybatisplus.toolkit;
  17. import java.sql.Timestamp;
  18. import java.util.concurrent.Executors;
  19. import java.util.concurrent.ScheduledExecutorService;
  20. import java.util.concurrent.ThreadFactory;
  21. import java.util.concurrent.TimeUnit;
  22. import java.util.concurrent.atomic.AtomicLong;
  23. /**
  24. * <p>
  25. * 高并发场景下System.currentTimeMillis()的性能问题的优化
  26. * </p>
  27. * <p>
  28. * System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右)<br>
  29. * System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道<br>
  30. * 后台定时更新时钟,JVM退出时,线程自动回收<br>
  31. * 10亿:43410,206,210.72815533980582%<br>
  32. * 1亿:4699,29,162.0344827586207%<br>
  33. * 1000万:480,12,40.0%<br>
  34. * 100万:50,10,5.0%<br>
  35. * </p>
  36. *
  37. * @author hubin
  38. * @Date 2016-08-01
  39. */
  40. public class SystemClock {
  41. private final long period;
  42. private final AtomicLong now;
  43. private SystemClock(long period) {
  44. this.period = period;
  45. this.now = new AtomicLong(System.currentTimeMillis());
  46. scheduleClockUpdating();
  47. }
  48. private static SystemClock instance() {
  49. return InstanceHolder.INSTANCE;
  50. }
  51. public static long now() {
  52. return instance().currentTimeMillis();
  53. }
  54. public static String nowDate() {
  55. return new Timestamp(instance().currentTimeMillis()).toString();
  56. }
  57. private void scheduleClockUpdating() {
  58. ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
  59. @Override
  60. public Thread newThread(Runnable runnable) {
  61. Thread thread = new Thread(runnable, "System Clock");
  62. thread.setDaemon(true);
  63. return thread;
  64. }
  65. });
  66. scheduler.scheduleAtFixedRate(new Runnable() {
  67. @Override
  68. public void run() {
  69. now.set(System.currentTimeMillis());
  70. }
  71. }, period, period, TimeUnit.MILLISECONDS);
  72. }
  73. private long currentTimeMillis() {
  74. return now.get();
  75. }
  76. private static class InstanceHolder {
  77. public static final SystemClock INSTANCE = new SystemClock(1);
  78. }
  79. }