提交 5fe29cdb authored 作者: 杨雪's avatar 杨雪

雪花算法、多线程雪花算法、改变ID中序列号位数的实现

上级
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/notes.iml" filepath="$PROJECT_DIR$/notes.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
差异被折叠。
单线程:
序号位数为12位时:31%
序号位数为13位时:31%
序号位数为14位时:31%
序号位数为15位时:85%
序号位数为16位时:98%
```chart
n12,31
n13,31
n14,31
n15,85
n16,98
type: line
title: 单线程:CPU与序列号位数之间的关系
x.title: 序列号位数
y.title: CPU使用率
y.suffix: %
```
* * *
多线程:
5个线程:
序号位数为12位时:75%
序号位数为16位时:98%
4个线程
序号位数为12位时:78%
序号位数为16位时:95%
3个线程
序号位数为12位时:74%
序号位数为16位时:95%
2个线程
序号位数为12位时:67%
序号位数为16位时:88%
```chart
,Two,Three,Four,Five
n12,67,74,78,75
n16,88,95,95,98
type: line
title: 多线程:CPU与序列号位数之间的关系
x.title: 序列号位数
y.title: CPU使用率
y.suffix: %
```
* * *
```chart
,十万,百万,千万
n12,3329,3720,3932
n13,5700,7253,7779
n14,7542,14311,14721
n15,7685,25183,28459,
n16,9347,47022,51143
type: line
title: QPS与序列号位数、生成ID个数之间的关系
x.title: 序列号位数
y.title: QPS
y.suffix: *1000
X.suffix: 位
```
```chart
,百万,千万
t2,3633,3897
t3,3800,3862
t4,3600,3936
t5,3634,3945
type: line
title: QPS与线程数、生成id个数之间的关系
x.title: 线程数
y.title: QPS
y.suffix: *1000
```
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
package increasethenumber;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author 杨雪
*/
public class IncreaseTheNumberOfID {
/**
* 当前时间戳
*/
private static final long START_TIMESTAMP = 1590368867576L;
/**
*机器编码在ID中占得位数
*/
private static final long WORK_ID = 0L;
private long serialNumber = 0L;
private long lastTimestamp = 0L;
public long newId(){
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp){
throw new RuntimeException("时钟回拨");
}
if (currentTimestamp == lastTimestamp){
if (serialNumber < 32767L){
serialNumber += 1;
}
if (serialNumber == 32767L){
serialNumber = 0L;
}
if (serialNumber == 0L){
while (lastTimestamp >= currentTimestamp){
currentTimestamp = System.currentTimeMillis();
}
lastTimestamp = currentTimestamp;
}
}else {
currentTimestamp = System.currentTimeMillis();
serialNumber = 0L;
lastTimestamp = currentTimestamp;
}
return ((currentTimestamp-START_TIMESTAMP) << 22L)
|(WORK_ID << 15L)
|serialNumber ;
}
public static void main(String[] args) {
IncreaseTheNumberOfID increaseTheNumberOfID = new IncreaseTheNumberOfID();
List<Long> idList = new ArrayList();
long start = System.currentTimeMillis();
for (int i = 0; i<1000_000; i++){
long id = increaseTheNumberOfID.newId();
}
long end = System.currentTimeMillis();
for (int i = 0; i<1000_000; i++){
idList.add(increaseTheNumberOfID.newId());
}
Set<Long> idSet = new HashSet<>(idList);
int num = 0;
long nowId;
/* for (int j=1; j<idList.size(); j++){
nowId = idList.get(j);
if (nowId > idList.get(j-1)){
num ++;
}
}
System.out.println("满足递增比较的次数:"+num);
System.out.println(" ");*/
System.out.println("总共生成id数:"+idList.size()
+" 花费时间为:"+(end-start)+"ms"
+" qps="+1000_000/(end-start)*1000);
System.out.println(" ");
System.out.println("list的id数量:"+idList.size()
+" set的id数量"+idSet.size());
}
}
package multithread;
import multithread.SnowFake;
import java.util.concurrent.atomic.AtomicLong;
public class MyRunnable implements Runnable {
private static final long START_TIMESTAMP = 1590368867576L;
/**
*机器编码在ID中占得位数
*/
private static final long WORK_ID = 0L;
private long serialNumber = 0L;
private long lastTimestamp = 0L;
private String taskNum;
private SnowFake snowFake;
private AtomicLong atomicLong;
public MyRunnable(SnowFake snowFake) {
this.snowFake = snowFake;
}
public MyRunnable(SnowFake snowFake, AtomicLong atomicLong) {
this.snowFake = snowFake;
this.atomicLong = atomicLong;
}
public MyRunnable() {
}
@Override
public void run() {
for (int i=0; i<=1000_000_000/2; i++) {
snowFake.newId();
atomicLong.incrementAndGet();
}
}
}
package multithread;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author 杨雪
*/
public class SnowFake {
/**
* 开始时间截(这个可以自己使用已经流逝的时间,我用的是自己写代码时的实际时间)
*/
private static final long START_STAMP = 1590368867576L;
/**
* 数据中心在id中占的位数
*/
private static final long DATA_CENTER_ID = 5L;
/**
* 机器码在id中占的位数
*/
private static final long MACHINE_ID = 1L;
/**
* 序列号在id中占得位数
*/
private static final long SERIAL_NUMBER = 16L;
/**
* 序列号最大值4095
*/
private static final long MAX_SERIAL_NUMBER = -1L ^ -1L << SERIAL_NUMBER;
private long dataCenter = 0L;
private long machineId = 0L;
private long serialNumber = 0L;
/**
* 上次生成ID的时间截
*/
private long lastTimestamp = 0L;
/**
* 数据标识id向左移17位(12+5)
*/
private final long datacenterIdLeft = SERIAL_NUMBER + MACHINE_ID;
/**
* 时间截向左移22位(5+5+12)
*/
private final long timestampLeftShift = SERIAL_NUMBER + MACHINE_ID + DATA_CENTER_ID;
public long getCurrentTimestamp() {
return System.currentTimeMillis();
}
public synchronized long newId() {
long currentTimestamp = getCurrentTimestamp();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException(
"出现时钟回拨异常");
}
if (currentTimestamp == lastTimestamp) {
serialNumber = (serialNumber + 1) & MAX_SERIAL_NUMBER;
if (serialNumber == 0L) {
while (lastTimestamp >= currentTimestamp) {
currentTimestamp = getCurrentTimestamp();
}
}
} else {
currentTimestamp = getCurrentTimestamp();
serialNumber = 0L;
}
lastTimestamp = currentTimestamp;
long l = ((currentTimestamp - START_STAMP) << timestampLeftShift)
| dataCenter << datacenterIdLeft
| (machineId << SERIAL_NUMBER)
| serialNumber;
return l;
}
}
package multithread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
public class TestThreadPool {
public static void main(String[] args) {
AtomicLong atomicLong = new AtomicLong(0);
int taskSize = 2;
// 创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
long start = System.currentTimeMillis();
SnowFake snowFake = new SnowFake();
for (int i =0; i <taskSize; i++){
pool.submit(new MyRunnable(snowFake, atomicLong));
}
while (atomicLong.get()!= 1000_000_000){
}
long end = System.currentTimeMillis();
System.out.println("qps:"+1000_000_000/(end-start)*1000);
}
}
package simplesnowfake;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author 杨雪
*/
public class SnowFake {
/**
* 开始时间截(这个可以自己使用已经流逝的时间,我用的是自己写代码时的实际时间)
*/
private static final long START_STAMP = 1590368867576L;
/**
* 数据中心在id中占的位数
*/
private static final long DATA_CENTER_ID = 5L ;
/**
* 机器码在id中占的位数
*/
private static final long MACHINE_ID = 1L;
/**
* 序列号在id中占得位数
*/
private static final long SERIAL_NUMBER = 16L;
/**
* 序列号最大值4095
*/
private static final long MAX_SERIAL_NUMBER = -1L ^ -1L << SERIAL_NUMBER;
private long dataCenter =0L;
private long machineId = 0L;
private long serialNumber = 0L;
/**
* 上次生成ID的时间截
*/
private long lastTimestamp = 0L;
/**
* 数据标识id向左移17位(12+5)
*/
private final long datacenterIdLeft = SERIAL_NUMBER + MACHINE_ID;
/**
* 时间截向左移22位(5+5+12)
*/
private final long timestampLeftShift = SERIAL_NUMBER + MACHINE_ID + DATA_CENTER_ID;
public long getCurrentTimestamp(){
return System.currentTimeMillis();
}
public synchronized long newId(){
long currentTimestamp = getCurrentTimestamp();
if (currentTimestamp < lastTimestamp){
throw new RuntimeException(
"出现时钟回拨异常");
}
if (currentTimestamp == lastTimestamp){
serialNumber =(serialNumber+1) & MAX_SERIAL_NUMBER;
if (serialNumber == 0L){
while(lastTimestamp >= currentTimestamp){
currentTimestamp = getCurrentTimestamp();
}
}
}else {
currentTimestamp = getCurrentTimestamp();
serialNumber = 0L;
}
lastTimestamp = currentTimestamp;
long l = ((currentTimestamp - START_STAMP) << timestampLeftShift)
| dataCenter << datacenterIdLeft
| (machineId << SERIAL_NUMBER)
| serialNumber;
return l;
}
public static void main(String[] args) {
SnowFake sf = new SnowFake();
List<Long> list = new ArrayList();
int i = 0;
long start = System.currentTimeMillis();
while (i <= 10_0000) {
i++;
long id = sf.newId();
}
long end = System.currentTimeMillis();
Set<Long> ids = new HashSet<>(list);
int num=1;
long nowId;
for (int i1=1;i1<list.size();i1++){
nowId = list.get(i1);
if(nowId>list.get(i1-1)){
num++;
}
}
System.out.println("满足递增比较的次数:"+num);
System.out.println("qps="+100000/(end-start)*1000);
System.out.println("总共生成"+ids.size()+"个ID,花费时间为"+(end - start)+"毫秒");
System.out.println(list.size());
System.out.println(ids.size());
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论