@@ -0,0 +1,258 @@ | |||||
## Ignore Visual Studio temporary files, build results, and | |||||
## files generated by popular Visual Studio add-ons. | |||||
# User-specific files | |||||
*.suo | |||||
*.user | |||||
*.userosscache | |||||
*.sln.docstates | |||||
*.editorconfig | |||||
# User-specific files (MonoDevelop/Xamarin Studio) | |||||
*.userprefs | |||||
# Build results | |||||
[Dd]ebug/ | |||||
[Dd]ebugPublic/ | |||||
[Rr]elease/ | |||||
[Rr]eleases/ | |||||
x64/ | |||||
x86/ | |||||
bld/ | |||||
[Bb]in/ | |||||
[Oo]bj/ | |||||
[Ll]og/ | |||||
# Visual Studio 2015 cache/options directory | |||||
**/.vs/ | |||||
# Uncomment if you have tasks that create the project's static files in wwwroot | |||||
#wwwroot/ | |||||
# MSTest test Results | |||||
[Tt]est[Rr]esult*/ | |||||
[Bb]uild[Ll]og.* | |||||
# NUNIT | |||||
*.VisualState.xml | |||||
TestResult.xml | |||||
# Build Results of an ATL Project | |||||
[Dd]ebugPS/ | |||||
[Rr]eleasePS/ | |||||
dlldata.c | |||||
# DNX | |||||
project.lock.json | |||||
artifacts/ | |||||
*_i.c | |||||
*_p.c | |||||
*_i.h | |||||
*.ilk | |||||
*.meta | |||||
*.obj | |||||
*.pch | |||||
*.pdb | |||||
*.pgc | |||||
*.pgd | |||||
*.rsp | |||||
*.sbr | |||||
*.tlb | |||||
*.tli | |||||
*.tlh | |||||
*.tmp | |||||
*.tmp_proj | |||||
*.log | |||||
*.vspscc | |||||
*.vssscc | |||||
.builds | |||||
*.pidb | |||||
*.svclog | |||||
*.scc | |||||
# Chutzpah Test files | |||||
_Chutzpah* | |||||
# Visual C++ cache files | |||||
ipch/ | |||||
*.aps | |||||
*.ncb | |||||
*.opendb | |||||
*.opensdf | |||||
*.sdf | |||||
*.cachefile | |||||
*.VC.db | |||||
*.VC.VC.opendb | |||||
# Visual Studio profiler | |||||
*.psess | |||||
*.vsp | |||||
*.vspx | |||||
*.sap | |||||
# TFS 2012 Local Workspace | |||||
$tf/ | |||||
# Guidance Automation Toolkit | |||||
*.gpState | |||||
# ReSharper is a .NET coding add-in | |||||
_ReSharper*/ | |||||
*.[Rr]e[Ss]harper | |||||
*.DotSettings.user | |||||
# JustCode is a .NET coding add-in | |||||
.JustCode | |||||
# TeamCity is a build add-in | |||||
_TeamCity* | |||||
# DotCover is a Code Coverage Tool | |||||
*.dotCover | |||||
# NCrunch | |||||
_NCrunch_* | |||||
.*crunch*.local.xml | |||||
nCrunchTemp_* | |||||
# MightyMoose | |||||
*.mm.* | |||||
AutoTest.Net/ | |||||
# Web workbench (sass) | |||||
.sass-cache/ | |||||
# Installshield output folder | |||||
[Ee]xpress/ | |||||
# DocProject is a documentation generator add-in | |||||
DocProject/buildhelp/ | |||||
DocProject/Help/*.HxT | |||||
DocProject/Help/*.HxC | |||||
DocProject/Help/*.hhc | |||||
DocProject/Help/*.hhk | |||||
DocProject/Help/*.hhp | |||||
DocProject/Help/Html2 | |||||
DocProject/Help/html | |||||
# Click-Once directory | |||||
publish/ | |||||
# Publish Web Output | |||||
*.[Pp]ublish.xml | |||||
*.azurePubxml | |||||
# TODO: Comment the next line if you want to checkin your web deploy settings | |||||
# but database connection strings (with potential passwords) will be unencrypted | |||||
*.pubxml | |||||
*.publishproj | |||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to | |||||
# checkin your Azure Web App publish settings, but sensitive information contained | |||||
# in these scripts will be unencrypted | |||||
PublishScripts/ | |||||
# NuGet Packages | |||||
*.nupkg | |||||
*.snupkg | |||||
# The packages folder can be ignored because of Package Restore | |||||
**/packages/* | |||||
# except build/, which is used as an MSBuild target. | |||||
!**/packages/build/ | |||||
# Uncomment if necessary however generally it will be regenerated when needed | |||||
#!**/packages/repositories.config | |||||
# NuGet v3's project.json files produces more ignoreable files | |||||
*.nuget.props | |||||
*.nuget.targets | |||||
# Microsoft Azure Build Output | |||||
csx/ | |||||
*.build.csdef | |||||
# Microsoft Azure Emulator | |||||
ecf/ | |||||
rcf/ | |||||
# Windows Store app package directories and files | |||||
AppPackages/ | |||||
BundleArtifacts/ | |||||
Package.StoreAssociation.xml | |||||
_pkginfo.txt | |||||
# Visual Studio cache files | |||||
# files ending in .cache can be ignored | |||||
*.[Cc]ache | |||||
# but keep track of directories ending in .cache | |||||
!*.[Cc]ache/ | |||||
# Others | |||||
ClientBin/ | |||||
~$* | |||||
*~ | |||||
*.dbmdl | |||||
*.dbproj.schemaview | |||||
*.pfx | |||||
*.publishsettings | |||||
node_modules/ | |||||
orleans.codegen.cs | |||||
# Since there are multiple workflows, uncomment next line to ignore bower_components | |||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||||
#bower_components/ | |||||
# RIA/Silverlight projects | |||||
Generated_Code/ | |||||
# Backup & report files from converting an old project file | |||||
# to a newer Visual Studio version. Backup files are not needed, | |||||
# because we have git ;-) | |||||
_UpgradeReport_Files/ | |||||
Backup*/ | |||||
UpgradeLog*.XML | |||||
UpgradeLog*.htm | |||||
# SQL Server files | |||||
*.mdf | |||||
*.ldf | |||||
# Business Intelligence projects | |||||
*.rdl.data | |||||
*.bim.layout | |||||
*.bim_*.settings | |||||
# Microsoft Fakes | |||||
FakesAssemblies/ | |||||
# GhostDoc plugin setting file | |||||
*.GhostDoc.xml | |||||
# Node.js Tools for Visual Studio | |||||
.ntvs_analysis.dat | |||||
# Visual Studio 6 build log | |||||
*.plg | |||||
# Visual Studio 6 workspace options file | |||||
*.opt | |||||
# Visual Studio LightSwitch build output | |||||
**/*.HTMLClient/GeneratedArtifacts | |||||
**/*.DesktopClient/GeneratedArtifacts | |||||
**/*.DesktopClient/ModelManifest.xml | |||||
**/*.Server/GeneratedArtifacts | |||||
**/*.Server/ModelManifest.xml | |||||
_Pvt_Extensions | |||||
# Paket dependency manager | |||||
.paket/paket.exe | |||||
paket-files/ | |||||
# FAKE - F# Make | |||||
.fake/ | |||||
# JetBrains Rider | |||||
.idea/ | |||||
*.sln.iml | |||||
# macOS | |||||
.DS_Store |
@@ -13,28 +13,28 @@ namespace Yitter.OrgSystem.TestA | |||||
private IIdGenerator IdGen; | private IIdGenerator IdGen; | ||||
private Hashtable ids = new Hashtable(); | private Hashtable ids = new Hashtable(); | ||||
public IList<long> idList = new List<long>(); | public IList<long> idList = new List<long>(); | ||||
private int GenNumber; | |||||
private int GenIdCount; | |||||
private int WorkerId; | private int WorkerId; | ||||
public GenTest(IIdGenerator idGen, int genNumber, int workerId) | |||||
public GenTest(IIdGenerator idGen, int genIdCount, int workerId) | |||||
{ | { | ||||
GenNumber = genNumber; | |||||
GenIdCount = genIdCount; | |||||
IdGen = idGen; | IdGen = idGen; | ||||
WorkerId = workerId; | WorkerId = workerId; | ||||
} | } | ||||
public void GenId() | |||||
{ | |||||
Thread t = new Thread(new ThreadStart(Gen1Start)); | |||||
t.Start(); | |||||
} | |||||
//public void GenId() | |||||
//{ | |||||
// Thread t = new Thread(new ThreadStart(Gen1Start)); | |||||
// t.Start(); | |||||
//} | |||||
private void Gen1Start() | |||||
public void GenStart() | |||||
{ | { | ||||
DateTime start = DateTime.Now; | DateTime start = DateTime.Now; | ||||
for (int i = 0; i < GenNumber; i++) | |||||
for (int i = 0; i < GenIdCount; i++) | |||||
{ | { | ||||
var id = IdGen.NewLong(); | var id = IdGen.NewLong(); | ||||
//ids.Add(id, i); | //ids.Add(id, i); |
@@ -28,7 +28,7 @@ namespace Yitter.OrgSystem.TestA | |||||
while (true) | while (true) | ||||
{ | { | ||||
Go(); | Go(); | ||||
Thread.Sleep(3000); // 每隔3秒执行一次Go | |||||
Thread.Sleep(1000); // 每隔3秒执行一次Go | |||||
Console.WriteLine("Hello World!"); | Console.WriteLine("Hello World!"); | ||||
} | } | ||||
} | } | ||||
@@ -43,7 +43,7 @@ namespace Yitter.OrgSystem.TestA | |||||
Method = method, | Method = method, | ||||
WorkerId = 1, | WorkerId = 1, | ||||
//TopOverCostCount = 2000, | |||||
TopOverCostCount = 10000, | |||||
//WorkerIdBitLength = 6, | //WorkerIdBitLength = 6, | ||||
//SeqBitLength = 9, | //SeqBitLength = 9, | ||||
@@ -56,10 +56,9 @@ namespace Yitter.OrgSystem.TestA | |||||
// ++++++++++++++++++++++++++++++++ | // ++++++++++++++++++++++++++++++++ | ||||
if (single) | if (single) | ||||
{ | { | ||||
IdGeneratorOptions options1 = (newConfig); | |||||
if (IdGen == null) | if (IdGen == null) | ||||
{ | { | ||||
IdGen = new DefaultIdGenerator(options1); | |||||
IdGen = new DefaultIdGenerator(newConfig); | |||||
} | } | ||||
if (outputLog) | if (outputLog) | ||||
@@ -86,7 +85,8 @@ namespace Yitter.OrgSystem.TestA | |||||
Console.WriteLine("Gen:" + i); | Console.WriteLine("Gen:" + i); | ||||
var test = new GenTest(IdGen, genIdCount, i); | var test = new GenTest(IdGen, genIdCount, i); | ||||
testList.Add(test); | testList.Add(test); | ||||
test.GenId(); | |||||
// test.GenId(); | |||||
test.GenStart(); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -117,7 +117,8 @@ namespace Yitter.OrgSystem.TestA | |||||
} | } | ||||
testList.Add(test); | testList.Add(test); | ||||
test.GenId(); | |||||
// test.GenId(); | |||||
test.GenStart(); | |||||
} | } | ||||
} | } | ||||
@@ -76,7 +76,6 @@ namespace Yitter.IdGenerator | |||||
SeqBitLength = options.SeqBitLength; | SeqBitLength = options.SeqBitLength; | ||||
MaxSeqNumber = options.MaxSeqNumber; | MaxSeqNumber = options.MaxSeqNumber; | ||||
MinSeqNumber = options.MinSeqNumber; | MinSeqNumber = options.MinSeqNumber; | ||||
_CurrentSeqNumber = options.MinSeqNumber; | |||||
TopOverCostCount = options.TopOverCostCount; | TopOverCostCount = options.TopOverCostCount; | ||||
if (options.StartTime != DateTime.MinValue) | if (options.StartTime != DateTime.MinValue) | ||||
@@ -91,12 +90,12 @@ namespace Yitter.IdGenerator | |||||
if (SeqBitLength == 0) | if (SeqBitLength == 0) | ||||
{ | { | ||||
SeqBitLength = 10; | |||||
SeqBitLength = 6; | |||||
} | } | ||||
if (WorkerIdBitLength == 0) | if (WorkerIdBitLength == 0) | ||||
{ | { | ||||
WorkerIdBitLength = 10; | |||||
WorkerIdBitLength = 6; | |||||
} | } | ||||
if (MaxSeqNumber == 0) | if (MaxSeqNumber == 0) | ||||
@@ -105,6 +104,7 @@ namespace Yitter.IdGenerator | |||||
} | } | ||||
_TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | ||||
_CurrentSeqNumber = options.MinSeqNumber; | |||||
} | } | ||||
@@ -0,0 +1,4 @@ | |||||
# idgenerator | |||||
something is going on. | |||||
@@ -0,0 +1,4 @@ | |||||
# idgenerator | |||||
something is going on. | |||||
@@ -0,0 +1,25 @@ | |||||
# Compiled class file | |||||
*.class | |||||
*.iml | |||||
# Log file | |||||
*.log | |||||
# BlueJ files | |||||
*.ctxt | |||||
# Mobile Tools for Java (J2ME) | |||||
.mtj.tmp/ | |||||
# Package Files # | |||||
*.jar | |||||
*.war | |||||
*.nar | |||||
*.ear | |||||
*.zip | |||||
*.tar.gz | |||||
*.rar | |||||
target/ | |||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | |||||
hs_err_pid* |
@@ -0,0 +1,201 @@ | |||||
Apache License | |||||
Version 2.0, January 2004 | |||||
http://www.apache.org/licenses/ | |||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||||
1. Definitions. | |||||
"License" shall mean the terms and conditions for use, reproduction, | |||||
and distribution as defined by Sections 1 through 9 of this document. | |||||
"Licensor" shall mean the copyright owner or entity authorized by | |||||
the copyright owner that is granting the License. | |||||
"Legal Entity" shall mean the union of the acting entity and all | |||||
other entities that control, are controlled by, or are under common | |||||
control with that entity. For the purposes of this definition, | |||||
"control" means (i) the power, direct or indirect, to cause the | |||||
direction or management of such entity, whether by contract or | |||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||||
outstanding shares, or (iii) beneficial ownership of such entity. | |||||
"You" (or "Your") shall mean an individual or Legal Entity | |||||
exercising permissions granted by this License. | |||||
"Source" form shall mean the preferred form for making modifications, | |||||
including but not limited to software source code, documentation | |||||
source, and configuration files. | |||||
"Object" form shall mean any form resulting from mechanical | |||||
transformation or translation of a Source form, including but | |||||
not limited to compiled object code, generated documentation, | |||||
and conversions to other media types. | |||||
"Work" shall mean the work of authorship, whether in Source or | |||||
Object form, made available under the License, as indicated by a | |||||
copyright notice that is included in or attached to the work | |||||
(an example is provided in the Appendix below). | |||||
"Derivative Works" shall mean any work, whether in Source or Object | |||||
form, that is based on (or derived from) the Work and for which the | |||||
editorial revisions, annotations, elaborations, or other modifications | |||||
represent, as a whole, an original work of authorship. For the purposes | |||||
of this License, Derivative Works shall not include works that remain | |||||
separable from, or merely link (or bind by name) to the interfaces of, | |||||
the Work and Derivative Works thereof. | |||||
"Contribution" shall mean any work of authorship, including | |||||
the original version of the Work and any modifications or additions | |||||
to that Work or Derivative Works thereof, that is intentionally | |||||
submitted to Licensor for inclusion in the Work by the copyright owner | |||||
or by an individual or Legal Entity authorized to submit on behalf of | |||||
the copyright owner. For the purposes of this definition, "submitted" | |||||
means any form of electronic, verbal, or written communication sent | |||||
to the Licensor or its representatives, including but not limited to | |||||
communication on electronic mailing lists, source code control systems, | |||||
and issue tracking systems that are managed by, or on behalf of, the | |||||
Licensor for the purpose of discussing and improving the Work, but | |||||
excluding communication that is conspicuously marked or otherwise | |||||
designated in writing by the copyright owner as "Not a Contribution." | |||||
"Contributor" shall mean Licensor and any individual or Legal Entity | |||||
on behalf of whom a Contribution has been received by Licensor and | |||||
subsequently incorporated within the Work. | |||||
2. Grant of Copyright License. Subject to the terms and conditions of | |||||
this License, each Contributor hereby grants to You a perpetual, | |||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||||
copyright license to reproduce, prepare Derivative Works of, | |||||
publicly display, publicly perform, sublicense, and distribute the | |||||
Work and such Derivative Works in Source or Object form. | |||||
3. Grant of Patent License. Subject to the terms and conditions of | |||||
this License, each Contributor hereby grants to You a perpetual, | |||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||||
(except as stated in this section) patent license to make, have made, | |||||
use, offer to sell, sell, import, and otherwise transfer the Work, | |||||
where such license applies only to those patent claims licensable | |||||
by such Contributor that are necessarily infringed by their | |||||
Contribution(s) alone or by combination of their Contribution(s) | |||||
with the Work to which such Contribution(s) was submitted. If You | |||||
institute patent litigation against any entity (including a | |||||
cross-claim or counterclaim in a lawsuit) alleging that the Work | |||||
or a Contribution incorporated within the Work constitutes direct | |||||
or contributory patent infringement, then any patent licenses | |||||
granted to You under this License for that Work shall terminate | |||||
as of the date such litigation is filed. | |||||
4. Redistribution. You may reproduce and distribute copies of the | |||||
Work or Derivative Works thereof in any medium, with or without | |||||
modifications, and in Source or Object form, provided that You | |||||
meet the following conditions: | |||||
(a) You must give any other recipients of the Work or | |||||
Derivative Works a copy of this License; and | |||||
(b) You must cause any modified files to carry prominent notices | |||||
stating that You changed the files; and | |||||
(c) You must retain, in the Source form of any Derivative Works | |||||
that You distribute, all copyright, patent, trademark, and | |||||
attribution notices from the Source form of the Work, | |||||
excluding those notices that do not pertain to any part of | |||||
the Derivative Works; and | |||||
(d) If the Work includes a "NOTICE" text file as part of its | |||||
distribution, then any Derivative Works that You distribute must | |||||
include a readable copy of the attribution notices contained | |||||
within such NOTICE file, excluding those notices that do not | |||||
pertain to any part of the Derivative Works, in at least one | |||||
of the following places: within a NOTICE text file distributed | |||||
as part of the Derivative Works; within the Source form or | |||||
documentation, if provided along with the Derivative Works; or, | |||||
within a display generated by the Derivative Works, if and | |||||
wherever such third-party notices normally appear. The contents | |||||
of the NOTICE file are for informational purposes only and | |||||
do not modify the License. You may add Your own attribution | |||||
notices within Derivative Works that You distribute, alongside | |||||
or as an addendum to the NOTICE text from the Work, provided | |||||
that such additional attribution notices cannot be construed | |||||
as modifying the License. | |||||
You may add Your own copyright statement to Your modifications and | |||||
may provide additional or different license terms and conditions | |||||
for use, reproduction, or distribution of Your modifications, or | |||||
for any such Derivative Works as a whole, provided Your use, | |||||
reproduction, and distribution of the Work otherwise complies with | |||||
the conditions stated in this License. | |||||
5. Submission of Contributions. Unless You explicitly state otherwise, | |||||
any Contribution intentionally submitted for inclusion in the Work | |||||
by You to the Licensor shall be under the terms and conditions of | |||||
this License, without any additional terms or conditions. | |||||
Notwithstanding the above, nothing herein shall supersede or modify | |||||
the terms of any separate license agreement you may have executed | |||||
with Licensor regarding such Contributions. | |||||
6. Trademarks. This License does not grant permission to use the trade | |||||
names, trademarks, service marks, or product names of the Licensor, | |||||
except as required for reasonable and customary use in describing the | |||||
origin of the Work and reproducing the content of the NOTICE file. | |||||
7. Disclaimer of Warranty. Unless required by applicable law or | |||||
agreed to in writing, Licensor provides the Work (and each | |||||
Contributor provides its Contributions) on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||||
implied, including, without limitation, any warranties or conditions | |||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||||
PARTICULAR PURPOSE. You are solely responsible for determining the | |||||
appropriateness of using or redistributing the Work and assume any | |||||
risks associated with Your exercise of permissions under this License. | |||||
8. Limitation of Liability. In no event and under no legal theory, | |||||
whether in tort (including negligence), contract, or otherwise, | |||||
unless required by applicable law (such as deliberate and grossly | |||||
negligent acts) or agreed to in writing, shall any Contributor be | |||||
liable to You for damages, including any direct, indirect, special, | |||||
incidental, or consequential damages of any character arising as a | |||||
result of this License or out of the use or inability to use the | |||||
Work (including but not limited to damages for loss of goodwill, | |||||
work stoppage, computer failure or malfunction, or any and all | |||||
other commercial damages or losses), even if such Contributor | |||||
has been advised of the possibility of such damages. | |||||
9. Accepting Warranty or Additional Liability. While redistributing | |||||
the Work or Derivative Works thereof, You may choose to offer, | |||||
and charge a fee for, acceptance of support, warranty, indemnity, | |||||
or other liability obligations and/or rights consistent with this | |||||
License. However, in accepting such obligations, You may act only | |||||
on Your own behalf and on Your sole responsibility, not on behalf | |||||
of any other Contributor, and only if You agree to indemnify, | |||||
defend, and hold each Contributor harmless for any liability | |||||
incurred by, or claims asserted against, such Contributor by reason | |||||
of your accepting any such warranty or additional liability. | |||||
END OF TERMS AND CONDITIONS | |||||
APPENDIX: How to apply the Apache License to your work. | |||||
To apply the Apache License to your work, attach the following | |||||
boilerplate notice, with the fields enclosed by brackets "[]" | |||||
replaced with your own identifying information. (Don't include | |||||
the brackets!) The text should be enclosed in the appropriate | |||||
comment syntax for the file format. We also recommend that a | |||||
file or class name and description of purpose be included on the | |||||
same "printed page" as the copyright notice for easier | |||||
identification within third-party archives. | |||||
Copyright [yyyy] [name of copyright owner] | |||||
Licensed under the Apache License, Version 2.0 (the "License"); | |||||
you may not use this file except in compliance with the License. | |||||
You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. |
@@ -0,0 +1,93 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<groupId>com.yitter</groupId> | |||||
<artifactId>yitter.idgenerator</artifactId> | |||||
<packaging>jar</packaging> | |||||
<version>1.0.0</version> | |||||
<name>yitter.idgenerator</name> | |||||
<description>Shorter ID and faster generation with a new snowflake drift algorithm. The core is to shorten the ID length, but also can have a very high instantaneous concurrent processing capacity (50W/0.1s), and powerful configuration capacity.</description> | |||||
<developers> | |||||
<developer> | |||||
<id>yitter</id> | |||||
<name>yitter</name> | |||||
<email>yitter@126.com</email> | |||||
<url>https://gitee.com/yitter/idgenerator</url> | |||||
</developer> | |||||
</developers> | |||||
<properties> | |||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
<maven.compiler.source>1.8</maven.compiler.source> | |||||
<maven.compiler.target>1.8</maven.compiler.target> | |||||
<java.version>1.8</java.version> | |||||
</properties> | |||||
<build> | |||||
<pluginManagement> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<version>3.8.0</version> | |||||
<configuration> | |||||
<source>${java.version}</source> | |||||
<target>${java.version}</target> | |||||
<encoding>UTF-8</encoding> | |||||
</configuration> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-jar-plugin</artifactId> | |||||
<version>3.1.0</version> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-surefire-plugin</artifactId> | |||||
<configuration> | |||||
<skip>true</skip> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</pluginManagement> | |||||
<resources> | |||||
<resource> | |||||
<directory>${project.basedir}</directory> | |||||
<targetPath>META-INF</targetPath> | |||||
<includes> | |||||
<include>LICENSE</include> | |||||
<include>NOTICE</include> | |||||
</includes> | |||||
</resource> | |||||
<resource> | |||||
<directory>src/main/resources</directory> | |||||
<filtering>true</filtering> | |||||
<includes> | |||||
<include>**</include> | |||||
</includes> | |||||
</resource> | |||||
</resources> | |||||
<testResources> | |||||
<testResource> | |||||
<directory>src/test/resources</directory> | |||||
<includes> | |||||
<include>**</include> | |||||
</includes> | |||||
</testResource> | |||||
</testResources> | |||||
</build> | |||||
<licenses> | |||||
<license> | |||||
<name>The Apache Software License, Version 2.0</name> | |||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> | |||||
</license> | |||||
</licenses> | |||||
</project> |
@@ -0,0 +1,9 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.contract; | |||||
public interface IIdGenerator { | |||||
long newLong() throws IdGeneratorException; | |||||
} |
@@ -0,0 +1,9 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.contract; | |||||
public interface ISnowWorker { | |||||
long nextId() throws IdGeneratorException; | |||||
} |
@@ -0,0 +1,28 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.contract; | |||||
public class IdGeneratorException extends RuntimeException { | |||||
public IdGeneratorException() { | |||||
super(); | |||||
} | |||||
public IdGeneratorException(String message) { | |||||
super(message); | |||||
} | |||||
public IdGeneratorException(Throwable cause) { | |||||
super(cause); | |||||
} | |||||
public IdGeneratorException(String message, Throwable cause) { | |||||
super(message, cause); | |||||
} | |||||
public IdGeneratorException(String msgFormat, Object... args) { | |||||
super(String.format(msgFormat, args)); | |||||
} | |||||
} |
@@ -0,0 +1,69 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.contract; | |||||
/** | |||||
* 雪花算法使用的参数 | |||||
* 此处代码不采用 get/set 那种冗长的写法 | |||||
*/ | |||||
public class IdGeneratorOptions { | |||||
/** | |||||
* 雪花计算方法 | |||||
* (1-漂移算法|2-传统算法),默认1 | |||||
*/ | |||||
public short Method = 1; | |||||
/** | |||||
* 开始时间 | |||||
* 不能超过当前系统时间 | |||||
*/ | |||||
public long StartTime = 0; | |||||
/** | |||||
* 机器码,必须由外部系统设置 | |||||
* 与 WorkerIdBitLength 有关系 | |||||
*/ | |||||
public short WorkerId = 0; | |||||
/** | |||||
* 机器码位长 | |||||
* 范围:2-21(要求:序列数位长+机器码位长不超过22)。 | |||||
* 建议范围:6-12。 | |||||
*/ | |||||
public byte WorkerIdBitLength = 6; | |||||
/** | |||||
* 序列数位长 | |||||
* 范围:2-21(要求:序列数位长+机器码位长不超过22)。 | |||||
* 建议范围:6-14。 | |||||
*/ | |||||
public byte SeqBitLength = 6; | |||||
/** | |||||
* 最大序列数(含) | |||||
* (由SeqBitLength计算的最大值) | |||||
*/ | |||||
public short MaxSeqNumber = 0; | |||||
/** | |||||
* 最小序列数(含) | |||||
* 默认11,不小于5,不大于MaxSeqNumber-2 | |||||
*/ | |||||
public short MinSeqNumber = 11; | |||||
/** | |||||
* 最大漂移次数(含) | |||||
* 默认2000,推荐范围500-10000(与计算能力有关) | |||||
*/ | |||||
public short TopOverCostCount = 2000; | |||||
public IdGeneratorOptions() { | |||||
} | |||||
public IdGeneratorOptions(short workerId) { | |||||
WorkerId = workerId; | |||||
} | |||||
} |
@@ -0,0 +1,51 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.contract; | |||||
/** | |||||
* Id生成时回调参数 | |||||
*/ | |||||
public class OverCostActionArg { | |||||
/** | |||||
* 事件类型 | |||||
* 1-开始,2-结束,8-漂移 | |||||
*/ | |||||
public int ActionType = 0; | |||||
/** | |||||
* 时间戳 | |||||
*/ | |||||
public long TimeTick = 0; | |||||
/** | |||||
* 机器码 | |||||
*/ | |||||
public short WorkerId = 0; | |||||
/** | |||||
* | |||||
*/ | |||||
public int OverCostCountInOneTerm = 0; | |||||
/** | |||||
* 漂移期间生产ID个数 | |||||
*/ | |||||
public int GenCountInOneTerm = 0; | |||||
/** | |||||
* 漂移周期 | |||||
*/ | |||||
public int TermIndex = 0; | |||||
public OverCostActionArg(short workerId, long timeTick, int actionType, int overCostCountInOneTerm, int genCountWhenOverCost, int index) { | |||||
ActionType = actionType; | |||||
TimeTick = timeTick; | |||||
WorkerId = workerId; | |||||
OverCostCountInOneTerm = overCostCountInOneTerm; | |||||
GenCountInOneTerm = genCountWhenOverCost; | |||||
TermIndex = index; | |||||
} | |||||
} |
@@ -0,0 +1,247 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.core; | |||||
import com.yitter.contract.ISnowWorker; | |||||
import com.yitter.contract.IdGeneratorException; | |||||
import com.yitter.contract.IdGeneratorOptions; | |||||
import com.yitter.contract.OverCostActionArg; | |||||
public class SnowWorkerM1 implements ISnowWorker { | |||||
/** | |||||
* 基础时间 | |||||
*/ | |||||
protected final long StartTimeUtc; | |||||
/** | |||||
* 机器码 | |||||
*/ | |||||
protected final short WorkerId; | |||||
/** | |||||
* 机器码位长 | |||||
* (机器码+序列数<=22位) | |||||
*/ | |||||
protected final byte WorkerIdBitLength; | |||||
/** | |||||
* 自增序列数位长 | |||||
* (机器码+序列数<=22位) | |||||
*/ | |||||
protected final byte SeqBitLength; | |||||
/** | |||||
* 最大序列数(含此值) | |||||
* 超过最大值,就会从MinSeqNumber开始 | |||||
*/ | |||||
protected final int MaxSeqNumber; | |||||
/** | |||||
* 最小序列数(含此值) | |||||
*/ | |||||
protected final short MinSeqNumber; | |||||
/** | |||||
* 最大漂移次数 | |||||
*/ | |||||
protected final int TopOverCostCount; | |||||
protected final byte _TimestampShift; | |||||
protected final static byte[] _SyncLock = new byte[0]; | |||||
protected short _CurrentSeqNumber; | |||||
protected long _LastTimeTick = -1L; | |||||
protected long _TurnBackTimeTick = -1L; | |||||
protected boolean _IsOverCost = false; | |||||
protected int _OverCostCountInOneTerm = 0; | |||||
protected int _GenCountInOneTerm = 0; | |||||
protected int _TermIndex = 0; | |||||
public SnowWorkerM1(IdGeneratorOptions options) { | |||||
WorkerId = options.WorkerId; | |||||
WorkerIdBitLength = options.WorkerIdBitLength == 0 ? 6 : options.WorkerIdBitLength; | |||||
SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength; | |||||
MaxSeqNumber = options.MaxSeqNumber > 0 ? options.MaxSeqNumber : (int) Math.pow(2, SeqBitLength); | |||||
MinSeqNumber = options.MinSeqNumber; | |||||
TopOverCostCount = options.TopOverCostCount; | |||||
StartTimeUtc = options.StartTime != 0 ? options.StartTime : 1582136402000L; | |||||
_TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength); | |||||
_CurrentSeqNumber = options.MinSeqNumber; | |||||
} | |||||
private void DoGenIdAction(OverCostActionArg arg) { | |||||
} | |||||
private void BeginOverCostCallBack(long useTimeTick) { | |||||
// if (GenAction == null) { | |||||
// return; | |||||
// } | |||||
// | |||||
// DoGenIdAction(new OverCostActionArg( | |||||
// WorkerId, | |||||
// useTimeTick, | |||||
// 1, | |||||
// _OverCostCountInOneTerm, | |||||
// _GenCountInOneTerm, | |||||
// _TermIndex)); | |||||
} | |||||
private void EndOverCostCallBack(long useTimeTick) { | |||||
if (_TermIndex > 10000) { | |||||
_TermIndex = 0; | |||||
} | |||||
// | |||||
// if (GenAction == null) { | |||||
// return; | |||||
// } | |||||
// | |||||
// DoGenIdAction(new OverCostActionArg( | |||||
// WorkerId, | |||||
// useTimeTick, | |||||
// 2, | |||||
// _OverCostCountInOneTerm, | |||||
// _GenCountInOneTerm, | |||||
// _TermIndex)); | |||||
} | |||||
private void TurnBackCallBack(long useTimeTick) { | |||||
// if (GenAction == null) { | |||||
// return; | |||||
// } | |||||
// | |||||
// DoGenIdAction(new OverCostActionArg( | |||||
// WorkerId, | |||||
// useTimeTick, | |||||
// 8, | |||||
// _OverCostCountInOneTerm, | |||||
// _GenCountInOneTerm, | |||||
// _TermIndex)); | |||||
} | |||||
private long NextOverCostId() { | |||||
long currentTimeTick = GetCurrentTimeTick(); | |||||
if (currentTimeTick > _LastTimeTick) { | |||||
EndOverCostCallBack(currentTimeTick); | |||||
_LastTimeTick = currentTimeTick; | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
_IsOverCost = false; | |||||
_OverCostCountInOneTerm = 0; | |||||
_GenCountInOneTerm = 0; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
if (_OverCostCountInOneTerm >= TopOverCostCount) { | |||||
EndOverCostCallBack(currentTimeTick); | |||||
_LastTimeTick = GetNextTimeTick(); | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
_IsOverCost = false; | |||||
_OverCostCountInOneTerm = 0; | |||||
_GenCountInOneTerm = 0; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
if (_CurrentSeqNumber > MaxSeqNumber) { | |||||
_LastTimeTick++; | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
_IsOverCost = true; | |||||
_OverCostCountInOneTerm++; | |||||
_GenCountInOneTerm++; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
_GenCountInOneTerm++; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
private long NextNormalId() throws IdGeneratorException { | |||||
long currentTimeTick = GetCurrentTimeTick(); | |||||
if (currentTimeTick > _LastTimeTick) { | |||||
_LastTimeTick = currentTimeTick; | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
if (_CurrentSeqNumber > MaxSeqNumber) { | |||||
BeginOverCostCallBack(currentTimeTick); | |||||
_TermIndex++; | |||||
_LastTimeTick++; | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
_IsOverCost = true; | |||||
_OverCostCountInOneTerm++; | |||||
_GenCountInOneTerm = 1; | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
if (currentTimeTick < _LastTimeTick) { | |||||
if (_TurnBackTimeTick < 1) { | |||||
_TurnBackTimeTick = _LastTimeTick - 1; | |||||
} | |||||
try { | |||||
Thread.sleep(10); | |||||
} catch (InterruptedException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
TurnBackCallBack(_TurnBackTimeTick); | |||||
return CalcTurnBackId(_TurnBackTimeTick); | |||||
} | |||||
return CalcId(_LastTimeTick); | |||||
} | |||||
private long CalcId(long useTimeTick) { | |||||
long result = ((useTimeTick << _TimestampShift) + | |||||
((long) WorkerId << SeqBitLength) + | |||||
(int) _CurrentSeqNumber); | |||||
_CurrentSeqNumber++; | |||||
return result; | |||||
} | |||||
private long CalcTurnBackId(long useTimeTick) { | |||||
long result = ((useTimeTick << _TimestampShift) + | |||||
((long) WorkerId << SeqBitLength) + 0); | |||||
_TurnBackTimeTick--; | |||||
return result; | |||||
} | |||||
protected long GetCurrentTimeTick() { | |||||
long millis = System.currentTimeMillis(); | |||||
return millis - StartTimeUtc; | |||||
} | |||||
protected long GetNextTimeTick() { | |||||
long tempTimeTicker = GetCurrentTimeTick(); | |||||
while (tempTimeTicker <= _LastTimeTick) { | |||||
tempTimeTicker = GetCurrentTimeTick(); | |||||
} | |||||
return tempTimeTicker; | |||||
} | |||||
@Override | |||||
public long nextId() { | |||||
synchronized (_SyncLock) { | |||||
return _IsOverCost ? NextOverCostId() : NextNormalId(); | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,41 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.core; | |||||
import com.yitter.contract.IdGeneratorException; | |||||
import com.yitter.contract.IdGeneratorOptions; | |||||
public class SnowWorkerM2 extends SnowWorkerM1 { | |||||
public SnowWorkerM2(IdGeneratorOptions options) { | |||||
super(options); | |||||
} | |||||
@Override | |||||
public long nextId() { | |||||
synchronized (_SyncLock) { | |||||
long currentTimeTick = GetCurrentTimeTick(); | |||||
if (_LastTimeTick == currentTimeTick) { | |||||
if (_CurrentSeqNumber++ > MaxSeqNumber) { | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
currentTimeTick = GetNextTimeTick(); | |||||
} | |||||
} else { | |||||
_CurrentSeqNumber = MinSeqNumber; | |||||
} | |||||
if (currentTimeTick < _LastTimeTick) { | |||||
throw new IdGeneratorException("Time error for {0} milliseconds", _LastTimeTick - currentTimeTick); | |||||
} | |||||
_LastTimeTick = currentTimeTick; | |||||
long result = ((currentTimeTick << _TimestampShift) + ((long) WorkerId << SeqBitLength) + (int) _CurrentSeqNumber); | |||||
return result; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,85 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.idgen; | |||||
import com.yitter.contract.ISnowWorker; | |||||
import com.yitter.contract.IdGeneratorException; | |||||
import com.yitter.contract.IdGeneratorOptions; | |||||
import com.yitter.contract.IIdGenerator; | |||||
import com.yitter.core.SnowWorkerM1; | |||||
import com.yitter.core.SnowWorkerM2; | |||||
public class DefaultIdGenerator implements IIdGenerator { | |||||
private final ISnowWorker _SnowWorker; | |||||
public DefaultIdGenerator(IdGeneratorOptions options) throws IdGeneratorException { | |||||
if (options == null) | |||||
{ | |||||
throw new IdGeneratorException("options error."); | |||||
} | |||||
if (options.StartTime > System.currentTimeMillis()) | |||||
{ | |||||
throw new IdGeneratorException("StartTime error."); | |||||
} | |||||
if (options.SeqBitLength + options.WorkerIdBitLength > 22) | |||||
{ | |||||
throw new IdGeneratorException("error:WorkerIdBitLength + SeqBitLength <= 22"); | |||||
} | |||||
double maxWorkerIdNumber = Math.pow(2, options.WorkerIdBitLength) - 1; | |||||
if (options.WorkerId < 1 || options.WorkerId > maxWorkerIdNumber) | |||||
{ | |||||
throw new IdGeneratorException("WorkerId error. (range:[1, " + maxWorkerIdNumber + "]"); | |||||
} | |||||
if (options.SeqBitLength < 2 || options.SeqBitLength > 21) | |||||
{ | |||||
throw new IdGeneratorException("SeqBitLength error. (range:[2, 21])"); | |||||
} | |||||
double maxSeqNumber = Math.pow(2, options.SeqBitLength) - 1; | |||||
if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) | |||||
{ | |||||
throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | |||||
} | |||||
double maxValue = maxSeqNumber - 2; | |||||
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue) | |||||
{ | |||||
throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxValue + "]"); | |||||
} | |||||
switch (options.Method) | |||||
{ | |||||
case 1: | |||||
_SnowWorker = new SnowWorkerM1(options); | |||||
break; | |||||
case 2: | |||||
_SnowWorker = new SnowWorkerM2(options); | |||||
break; | |||||
default: | |||||
_SnowWorker = new SnowWorkerM1(options); | |||||
break; | |||||
} | |||||
if (options.Method == 1) | |||||
{ | |||||
try { | |||||
Thread.sleep(500); | |||||
} catch (InterruptedException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
@Override | |||||
public long newLong() { | |||||
return _SnowWorker.nextId(); | |||||
} | |||||
} |
@@ -0,0 +1,45 @@ | |||||
/* | |||||
* 版权属于:yitter(yitter@126.com) | |||||
* 开源地址:https://gitee.com/yitter/idgenerator | |||||
*/ | |||||
package com.yitter.idgen; | |||||
import com.yitter.contract.IdGeneratorException; | |||||
import com.yitter.contract.IdGeneratorOptions; | |||||
import com.yitter.contract.IIdGenerator; | |||||
/** | |||||
* 这是一个调用的例子,默认情况下,单机集成者可以直接使用 NewId()。 | |||||
*/ | |||||
public class IdHelper { | |||||
private static IIdGenerator idGenInstance = null; | |||||
public static IIdGenerator getIdGenInstance() | |||||
{ | |||||
return idGenInstance; | |||||
} | |||||
/** | |||||
* 设置参数,建议程序初始化时执行一次 | |||||
* @param options | |||||
*/ | |||||
public static void setIdGenerator(IdGeneratorOptions options) throws IdGeneratorException { | |||||
idGenInstance = new DefaultIdGenerator(options); | |||||
} | |||||
/** | |||||
* 生成新的Id | |||||
* 调用本方法前,请确保调用了 SetIdGenerator 方法做初始化。 | |||||
* @return | |||||
*/ | |||||
public static long nextId() throws IdGeneratorException { | |||||
if (idGenInstance == null) | |||||
{ | |||||
idGenInstance = new DefaultIdGenerator(new IdGeneratorOptions((short)1)); | |||||
} | |||||
return idGenInstance.newLong(); | |||||
} | |||||
} |
@@ -0,0 +1,31 @@ | |||||
package com.yitter.test; | |||||
import com.yitter.contract.IIdGenerator; | |||||
public class GenTest { | |||||
private IIdGenerator IdGen; | |||||
private int GenIdCount; | |||||
private int WorkerId; | |||||
public GenTest(IIdGenerator idGen, int genIdCount, int workerId) { | |||||
GenIdCount = genIdCount; | |||||
IdGen = idGen; | |||||
WorkerId = workerId; | |||||
} | |||||
public void GenStart() { | |||||
long start = System.currentTimeMillis(); | |||||
for (int i = 0; i < GenIdCount; i++) { | |||||
long id = IdGen.newLong(); | |||||
} | |||||
long end = System.currentTimeMillis(); | |||||
long time = end - start; | |||||
System.out.println("++++++++++++++++++++++++++++++++++++++++WorkerId: " | |||||
+ WorkerId + ", total: " + time + " ms"); | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
package com.yitter.test; | |||||
import com.yitter.contract.IdGeneratorOptions; | |||||
import com.yitter.contract.IIdGenerator; | |||||
import com.yitter.idgen.DefaultIdGenerator; | |||||
import com.yitter.idgen.IdHelper; | |||||
public class StartUp { | |||||
/** | |||||
* 测试结果: | |||||
* (1):1W并发,方法 1只要 1ms.而方法 2 要 180ms。 | |||||
* (2):5W并发,方法 1只要 9ms.而方法 2 要 900ms。 | |||||
* [不同CPU可能结果有差异,但相对大小不变] | |||||
* 默认配置下,最佳性能是5W/s-8W/s | |||||
*/ | |||||
final static int genIdCount = 50000; | |||||
//1-漂移算法,2-传统算法 | |||||
final static short method = 1; | |||||
public static void main(String[] args) { | |||||
IdGeneratorOptions options = new IdGeneratorOptions(); | |||||
//options.TopOverCostCount = 10000; | |||||
// options.WorkerIdBitLength = 6; | |||||
// options.SeqBitLength = 9; | |||||
// options.MinSeqNumber = 11; | |||||
// options.MaxSeqNumber = 200; | |||||
options.Method = method; | |||||
options.WorkerId = 1; | |||||
options.StartTime = 1582206693000L; // (2020-2-20) | |||||
IIdGenerator IdGen = new DefaultIdGenerator(options); | |||||
GenTest genTest = new GenTest(IdGen, genIdCount, options.WorkerId); | |||||
// 首先测试一下 IdHelper 方法,获取单个Id | |||||
IdHelper.setIdGenerator(options); | |||||
long newId = IdHelper.nextId(); | |||||
System.out.println("====================================="); | |||||
System.out.println("这是用方法 " + method + " 生成的 Id:" + newId); | |||||
// 然后循环测试一下,看看并发请求时的耗时情况 | |||||
try { | |||||
while (true) { | |||||
genTest.GenStart(); | |||||
Thread.sleep(1000); // 每隔1秒执行一次GenStart | |||||
System.out.println("Hello World!"); | |||||
} | |||||
} catch (InterruptedException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,4 @@ | |||||
# idgenerator | |||||
something is going on. | |||||