From a5259c5238cf07b9a51b429a144eeac21864159e Mon Sep 17 00:00:00 2001 From: whycq <913841844@qq.com> Date: 星期三, 14 八月 2024 17:01:45 +0800 Subject: [PATCH] # --- app/src/main/java/com/example/agvcontroller/utils/SnowflakeIdWorker.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 162 insertions(+), 0 deletions(-) diff --git a/app/src/main/java/com/example/agvcontroller/utils/SnowflakeIdWorker.java b/app/src/main/java/com/example/agvcontroller/utils/SnowflakeIdWorker.java new file mode 100644 index 0000000..306c764 --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/utils/SnowflakeIdWorker.java @@ -0,0 +1,162 @@ +package com.example.agvcontroller.utils; + +/** + * Twitter_Snowflake<br> + * SnowFlake鐨勭粨鏋勫涓�(姣忛儴鍒嗙敤-鍒嗗紑):<br> + * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - + * 000000000000 <br> + * 1浣嶆爣璇嗭紝鐢变簬long鍩烘湰绫诲瀷鍦↗ava涓槸甯︾鍙风殑锛屾渶楂樹綅鏄鍙蜂綅锛屾鏁版槸0锛岃礋鏁版槸1锛屾墍浠d涓�鑸槸姝f暟锛屾渶楂樹綅鏄�0<br> + * 41浣嶆椂闂存埅(姣绾�)锛屾敞鎰忥紝41浣嶆椂闂存埅涓嶆槸瀛樺偍褰撳墠鏃堕棿鐨勬椂闂存埅锛岃�屾槸瀛樺偍鏃堕棿鎴殑宸�硷紙褰撳墠鏃堕棿鎴� - 寮�濮嬫椂闂存埅) + * 寰楀埌鐨勫�硷級锛岃繖閲岀殑鐨勫紑濮嬫椂闂存埅锛屼竴鑸槸鎴戜滑鐨刬d鐢熸垚鍣ㄥ紑濮嬩娇鐢ㄧ殑鏃堕棿锛岀敱鎴戜滑绋嬪簭鏉ユ寚瀹氱殑锛堝涓嬩笅闈㈢▼搴廔dWorker绫荤殑startTime灞炴�э級銆�41浣嶇殑鏃堕棿鎴紝鍙互浣跨敤69骞达紝骞碩 + * = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br> + * 10浣嶇殑鏁版嵁鏈哄櫒浣嶏紝鍙互閮ㄧ讲鍦�1024涓妭鐐癸紝鍖呮嫭5浣峝atacenterId鍜�5浣峸orkerId<br> + * 12浣嶅簭鍒楋紝姣鍐呯殑璁℃暟锛�12浣嶇殑璁℃暟椤哄簭鍙锋敮鎸佹瘡涓妭鐐规瘡姣(鍚屼竴鏈哄櫒锛屽悓涓�鏃堕棿鎴�)浜х敓4096涓狪D搴忓彿<br> + * 鍔犺捣鏉ュ垰濂�64浣嶏紝涓轰竴涓狶ong鍨嬨��<br> + * SnowFlake鐨勪紭鐐规槸锛屾暣浣撲笂鎸夌収鏃堕棿鑷鎺掑簭锛屽苟涓旀暣涓垎甯冨紡绯荤粺鍐呬笉浼氫骇鐢烮D纰版挒(鐢辨暟鎹腑蹇僆D鍜屾満鍣↖D浣滃尯鍒�)锛屽苟涓旀晥鐜囪緝楂橈紝缁忔祴璇曪紝SnowFlake姣忕鑳藉浜х敓26涓嘔D宸﹀彸銆� + */ +public class SnowflakeIdWorker { + + // ==============================Fields=========================================== + /** 寮�濮嬫椂闂存埅 (2015-01-01) */ + private final long twepoch = 1420041600000L; + + /** 搴忓垪鍊兼墍鍗犵殑浣嶆暟 */ + private final long sequenceBits = 12L; + + /** 鏈哄櫒id鎵�鍗犵殑浣嶆暟 */ + private final long workerIdBits = 5L; + + /** 鏈烘埧id鎵�鍗犵殑浣嶆暟 */ + private final long datacenterIdBits = 5L; + + /** 鏈哄櫒id鍚戝乏绉�12浣� */ + private final long workerIdLeftShift = sequenceBits; + + /** 鏈烘埧id鍚戝乏绉�17浣�(5+12) */ + private final long datacenterIdLeftShift =workerIdLeftShift + workerIdBits; + + /** 鏃堕棿鎴悜宸︾Щ22浣�(5+5+12) */ + private final long timestampLeftShift = datacenterIdLeftShift + datacenterIdBits; + + /** 鏀寔鐨勬渶澶ф満鍣╥d (浣嶆暟浜岃繘鍒跺��) */ + private final long maxWorkerId = -1L ^ (-1L << workerIdBits); + + /** 鏀寔鐨勬渶澶ф暟鎹爣璇唅d (浣嶆暟浜岃繘鍒跺��) */ + private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + + /**鐢熸垚搴忓垪鐨勬帺鐮� */ + private final long sequenceMask = -1L ^ (-1L << sequenceBits); + + /** 宸ヤ綔鏈哄櫒ID(0~31) */ + private long workerId; + + /** 鏁版嵁涓績ID(0~31) */ + private long datacenterId; + + /** 姣鍐呭簭鍒� */ + private long sequence = 0L; + + /** 涓婃鐢熸垚ID鐨勬椂闂存埅 */ + private long lastTimestamp = -1L; + + // ==============================Constructors===================================== + + /** + * 鏋勯�犲嚱鏁� + * + * @param workerId + * 宸ヤ綔ID (0~31) + * @param datacenterId + * 鏁版嵁涓績ID (0~31) + */ + public SnowflakeIdWorker(long workerId, long datacenterId) { + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException( + String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException( + String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + public SnowflakeIdWorker(){ + this(0L, 0L); + } + + // ==============================Methods========================================== + /** + * 鑾峰緱涓嬩竴涓狪D (璇ユ柟娉曟槸绾跨▼瀹夊叏鐨�) + * + * @return SnowflakeId + */ + public synchronized long nextId() { + long timestamp = timeGen(); + + // 濡傛灉褰撳墠鏃堕棿灏忎簬涓婁竴娆D鐢熸垚鐨勬椂闂存埑锛岃鏄庣郴缁熸椂閽熷洖閫�杩囪繖涓椂鍊欏簲褰撴姏鍑哄紓甯� + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format( + "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + // 濡傛灉鏄悓涓�鏃堕棿鐢熸垚鐨勶紝鍒欒繘琛屾绉掑唴搴忓垪 + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & sequenceMask; + // 姣鍐呭簭鍒楁孩鍑� + if (sequence == 0) { + // 闃诲鍒颁笅涓�涓绉�,鑾峰緱鏂扮殑鏃堕棿鎴� + timestamp = tilNextMillis(lastTimestamp); + } + } + // 鏃堕棿鎴虫敼鍙橈紝姣鍐呭簭鍒楅噸缃� + else { + sequence = 0L; + } + + // 涓婃鐢熸垚ID鐨勬椂闂存埅 + lastTimestamp = timestamp; + + // 绉讳綅骞堕�氳繃鎴栬繍绠楁嫾鍒颁竴璧风粍鎴�64浣嶇殑ID + return ((timestamp - twepoch) << timestampLeftShift) // + | (datacenterId << datacenterIdLeftShift) // + | (workerId << workerIdLeftShift) // + | sequence; + } + + /** + * 闃诲鍒颁笅涓�涓绉掞紝鐩村埌鑾峰緱鏂扮殑鏃堕棿鎴� + * + * @param lastTimestamp + * 涓婃鐢熸垚ID鐨勬椂闂存埅 + * @return 褰撳墠鏃堕棿鎴� + */ + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + /** + * 杩斿洖浠ユ绉掍负鍗曚綅鐨勫綋鍓嶆椂闂� + * + * @return 褰撳墠鏃堕棿(姣) + */ + protected long timeGen() { + return System.currentTimeMillis(); + } + + // ==============================Test============================================= + /** 娴嬭瘯 */ + public static void main(String[] args) { + SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); + for (int i = 0; i < 1000; i++) { + long id = idWorker.nextId(); + System.out.println(Long.toBinaryString(id)); + System.out.println(id); + } + } +} -- Gitblit v1.9.1