Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2e21974

Browse filesBrowse files
committed
add snowId
1 parent 15ef0f4 commit 2e21974
Copy full SHA for 2e21974

File tree

Expand file treeCollapse file tree

3 files changed

+156
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+156
-0
lines changed
Open diff view settings
Collapse file
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.learnjava.concurent;
2+
3+
/**
4+
* @author lhy
5+
* @date 2021/7/27
6+
*/
7+
public class SnowIdDemo {
8+
public static void main(String[] args) {
9+
// 通过雪花秀算法获取分布式id
10+
System.out.println(SnowIdUtils.uniqueLongHex());
11+
}
12+
}
Collapse file
+114Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.learnjava.concurent;
2+
3+
/**
4+
* @author lhy
5+
* @date 2021/7/27
6+
*/
7+
public class SnowIdUtils {
8+
/**
9+
* 私有的 静态内部类
10+
*/
11+
private static class SnowFlake {
12+
13+
/**
14+
* 内部类对象(单例模式)
15+
*/
16+
private static final SnowIdUtils.SnowFlake SNOW_FLAKE = new SnowIdUtils.SnowFlake();
17+
/**
18+
* 起始的时间戳
19+
*/
20+
private final long START_TIMESTAMP = 1609464335121L;
21+
/**
22+
* 序列号占用位数
23+
*/
24+
private final long SEQUENCE_BIT = 12;
25+
/**
26+
* 机器标识占用位数
27+
*/
28+
private final long MACHINE_BIT = 10;
29+
/**
30+
* 时间戳位移位数
31+
*/
32+
private final long TIMESTAMP_LEFT = SEQUENCE_BIT + MACHINE_BIT;
33+
/**
34+
* 最大序列号 (4095)
35+
*/
36+
private final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
37+
/**
38+
* 最大机器编号 (1023)
39+
*/
40+
private final long MAX_MACHINE_ID = ~(-1L << MACHINE_BIT);
41+
/**
42+
* 生成id机器标识部分
43+
*/
44+
private long machineIdPart;
45+
/**
46+
* 序列号
47+
*/
48+
private long sequence = 0L;
49+
/**
50+
* 上一次时间戳
51+
*/
52+
private long lastStamp = -1L;
53+
54+
/**
55+
* 构造函数初始化机器编码
56+
*/
57+
private SnowFlake() {
58+
// String ip = instance.getDockerIp().replace(".", "");
59+
// 模拟获取机器节点ip
60+
String ip = "127.0.0.1";
61+
long localIp = Long.valueOf(ip.replace(".", ""));
62+
machineIdPart = (localIp & MAX_MACHINE_ID) << SEQUENCE_BIT;
63+
}
64+
/**
65+
* 获取雪花ID
66+
*/
67+
public synchronized long nextId() {
68+
long currentStamp = timeGen();
69+
while (currentStamp < lastStamp) {
70+
throw new RuntimeException(String.format("时钟已经回拨. Refusing to generate id for %d milliseconds", lastStamp - currentStamp));
71+
}
72+
if (currentStamp == lastStamp) {
73+
sequence = (sequence + 1) & MAX_SEQUENCE;
74+
if (sequence == 0) {
75+
currentStamp = getNextMill();
76+
}
77+
} else {
78+
sequence = 0L;
79+
}
80+
lastStamp = currentStamp;
81+
return (currentStamp - START_TIMESTAMP) << TIMESTAMP_LEFT | machineIdPart | sequence;
82+
}
83+
/**
84+
* 阻塞到下一个毫秒,直到获得新的时间戳
85+
*/
86+
private long getNextMill() {
87+
long mill = timeGen();
88+
//
89+
while (mill <= lastStamp) {
90+
mill = timeGen();
91+
}
92+
return mill;
93+
}
94+
/**
95+
* 返回以毫秒为单位的当前时间
96+
*/
97+
protected long timeGen() {
98+
return System.currentTimeMillis();
99+
}
100+
}
101+
102+
/**
103+
* 获取long类型雪花ID
104+
*/
105+
public static long uniqueLong() {
106+
return SnowIdUtils.SnowFlake.SNOW_FLAKE.nextId();
107+
}
108+
/**
109+
* 获取String类型雪花ID
110+
*/
111+
public static String uniqueLongHex() {
112+
return String.format("%016X", uniqueLong());
113+
}
114+
}
Collapse file

‎JdkLearn/src/main/java/com/learnjava/optimization/OptimizeDemo.java‎

Copy file name to clipboardExpand all lines: JdkLearn/src/main/java/com/learnjava/optimization/OptimizeDemo.java
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.HashMap;
44
import java.util.Map;
5+
import java.util.concurrent.ConcurrentHashMap;
56

67
/**
78
*
@@ -14,6 +15,9 @@ public class OptimizeDemo {
1415
public static void main(String[] args) {
1516
Map<String, Integer> map = new HashMap<>();
1617
mergeData(map);
18+
19+
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
20+
concurrentMergeData(concurrentMap);
1721
}
1822

1923
/**
@@ -34,7 +38,33 @@ public static void mergeData(Map<String, Integer> map) {
3438
Integer mapValue = map.get(key);
3539
if (null != mapValue) {
3640
mapValue += value;
41+
} else {
42+
mapValue = value;
3743
}
3844
map.put(key, mapValue);
3945
}
46+
47+
/**
48+
* 针对mergeData里map的put操作,在并发情况下会存在put的时候,以及有其他线程已经put成功了,导致线程不安全,
49+
* 所以需要使用并发集合列的putIfAbsent方法
50+
* @param map
51+
*/
52+
public static void concurrentMergeData(Map<String, Integer> map) {
53+
String key = "mapKey";
54+
int value = 1;
55+
Integer mapValue = map.get(key);
56+
if (null != mapValue) {
57+
mapValue += value;
58+
} else {
59+
mapValue = value;
60+
}
61+
map.putIfAbsent(key, mapValue);
62+
63+
// computeIfAbsent方法对map中的key只进行重新计算,如果不存在这个key,则添加到map中
64+
map.computeIfAbsent(key, (k) -> {
65+
// 其他计算
66+
int a = 1, b = 2;
67+
return a + b;
68+
});
69+
}
4070
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.