国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java收集的雪花算法代碼詳解

Java收集的雪花算法代碼詳解

2022-02-13 15:00java265 Java教程

這篇文章主要介紹了Java實現雪花算法的詳細代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.java265.other;
 
 
public class Test {
 
    // 因為二進制里第一個 bit 為如果是 1,那么都是負數,但是我們生成的 id 都是正數,所以第一個 bit 統一都是 0。
 
    // 機器ID 2進制5位 32位減掉1位 31個
    private long workerId;
    // 機房ID 2進制5位 32位減掉1位 31個
    private long datacenterId;
    // 代表一毫秒內生成的多個id的最新序號 12位 4096 -1 = 4095 個
    private long sequence;
    // 設置一個時間初始值 2^41 - 1 差不多可以用69年
    private long twepoch = 1585644268888L;
    // 5位的機器id
    private long workerIdBits = 5L;
    // 5位的機房id
    private long datacenterIdBits = 5L;
    // 每毫秒內產生的id數 2 的 12次方
    private long sequenceBits = 12L;
    // 這個是二進制運算,就是5 bit最多只能有31個數字,也就是說機器id最多只能是32以內
    private long maxWorkerId = -1L ^ (-1L << workerIdBits);
    // 這個是一個意思,就是5 bit最多只能有31個數字,機房id最多只能是32以內
    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
 
    private long workerIdShift = sequenceBits;
    private long datacenterIdShift = sequenceBits + workerIdBits;
    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private long sequenceMask = -1L ^ (-1L << sequenceBits);
    // 記錄產生時間毫秒數,判斷是否是同1毫秒
    private long lastTimestamp = -1L;
 
    public long getWorkerId() {
        return workerId;
    }
 
    public long getDatacenterId() {
        return datacenterId;
    }
 
    public long getTimestamp() {
        return System.currentTimeMillis();
    }
 
    public Test(long workerId, long datacenterId, long sequence) {
 
        // 檢查機房id和機器id是否超過31 不能小于0
        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;
        this.sequence = sequence;
    }
 
    // 這個是核心方法,通過調用nextId()方法,讓當前這臺機器上的snowflake算法程序生成一個全局唯一的id
    public synchronized long nextId() {
        // 這兒就是獲取當前時間戳,單位是毫秒
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
 
            System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp);
            throw new RuntimeException(String.format(
                    "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }
 
        // 下面是說假設在同一個毫秒內,又發送了一個請求生成一個id
        // 這個時候就得把seqence序號給遞增1,最多就是4096
        if (lastTimestamp == timestamp) {
 
            // 這個意思是說一個毫秒內最多只能有4096個數字,無論你傳遞多少進來,
            // 這個位運算保證始終就是在4096這個范圍內,避免你自己傳遞個sequence超過了4096這個范圍
            sequence = (sequence + 1) & sequenceMask;
            // 當某一毫秒的時間,產生的id數 超過4095,系統會進入等待,直到下一毫秒,系統繼續產生ID
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
 
        } else {
            sequence = 0;
        }
        // 這兒記錄一下最近一次生成id的時間戳,單位是毫秒
        lastTimestamp = timestamp;
        // 這兒就是最核心的二進制位運算操作,生成一個64bit的id
        // 先將當前時間戳左移,放到41 bit那兒;將機房id左移放到5 bit那兒;將機器id左移放到5 bit那兒;將序號放最后12 bit
        // 最后拼接起來成一個64 bit的二進制數字,轉換成10進制就是個long型
        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift)
                | (workerId << workerIdShift) | sequence;
    }
 
    /**
     * 當某一毫秒的時間,產生的id數 超過4095,系統會進入等待,直到下一毫秒,系統繼續產生ID
     *
     * @param lastTimestamp
     * @return
     */
    private long tilNextMillis(long lastTimestamp) {
 
        long timestamp = timeGen();
 
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }
 
    // 獲取當前時間戳
    private long timeGen() {
        return System.currentTimeMillis();
    }
 
    /**
     * main 測試類
     *
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(1 & 4596);
        System.out.println(2 & 4596);
        System.out.println(6 & 4596);
        System.out.println(6 & 4596);
        System.out.println(6 & 4596);
        System.out.println(6 & 4596);
        Test test = new Test(1, 1, 1);
        for (int i = 0; i < 22; i++) {
            System.out.println(test.nextId());
        }
    }
}

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://www.cnblogs.com/java265/p/15370568.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人在线视频网站 | 欧美日韩亚洲二区 | 国产99久久 | 依人在线免费视频 | 91视频免费网站 | 91精品国产乱码久久久久久 | 成人h视频 | 中文字幕精品一区二区精品 | 久久99精品国产.久久久久 | 中文字幕一区二区三区乱码图片 | 亚洲一区欧美 | 在线精品国产 | 成人免费淫片aa视频免费 | 国产中文字幕在线 | 日韩欧美在线观看 | 国产一区二区久久 | 成人综合网站 | 久久久国产精品免费 | 久久精品91 | 99久久久国产精品 | 日日夜夜国产 | 日韩一级精品视频在线观看 | 亚洲欧美国产精品专区久久 | 亚洲欧美一区二区三区在线 | av在线电影网站 | 中文字字幕一区二区三区四区五区 | 精品福利一区二区三区 | 一本久久综合亚洲鲁鲁五月天 | 欧美综合在线观看 | 久久久久久av | 亚洲欧美日韩系列 | 亚洲91| 国产精品一二三区 | 成人av播放 | 亚洲一区在线免费观看 | 久久综合国产 | 欧美狠狠操 | 日韩av免费播放 | 亚洲 中文 欧美 日韩 在线观看 | 日韩有码一区 | 欧美日韩亚洲成人 |