提交 cb73b3a0 authored 作者: 黄夏豪's avatar 黄夏豪

Merge remote-tracking branch 'origin/master'

package cn.xy.snowflake;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SnowflakeDemo {
//分割长度
private final long sequenceLength = 12L;
private final long workerIdLength = 10L;
private final long lastTimeStampLength = 41L;
//偏移量
private final long workerIdShift = sequenceLength;
private final long lastTimeStampShift = sequenceLength + workerIdLength;
//初始化
private long lastTimeStamp = -1L;
private long workerId;
private long workerId = 0L;
private long sequence = 0L;
//掩码
private long mark = ~(-1L << sequenceLength);
private static final int loopNum = 1*10000;
private static final int loopNum = 10_000;
//请求总数
public static int clientTotal = 5000;
//同时并发执行的线程数
public static int threadTotal = 200;
public synchronized String getId() {
long timeStamp = System.currentTimeMillis();
......@@ -40,16 +53,9 @@ public class SnowflakeDemo {
sequence = 0;
}
lastTimeStamp = timeStamp;
return Long.toBinaryString(sequence | (workerId << workerIdShift) | (timeStamp << lastTimeStampShift));
}
public synchronized long waitTime(long lastTimeStamp) {
long timeStamp = System.currentTimeMillis();
while(timeStamp <= lastTimeStamp) {
timeStamp = System.currentTimeMillis();
}
return timeStamp;
String res = Thread.currentThread().getName() + " " + Long.toBinaryString(sequence | (workerId << workerIdShift) | (timeStamp << lastTimeStampShift));
System.out.println(Thread.currentThread().getName() + " " + res);
return res;
}
private SnowflakeDemo(){}
......@@ -65,38 +71,76 @@ public class SnowflakeDemo {
long currentTime = System.currentTimeMillis();
SnowflakeDemo snowflakeDemo = new SnowflakeDemo(currentTime, 0, 0);
for (int index = 0; index < loopNum; index++) {
int finalIndex = index;
Runnable run = new Runnable() {
public void run() {
try {
//new Thread().sleep(1000); //模拟耗时操作
System.out.println("[1]" + Thread.currentThread().getName() + " " + snowflakeDemo.getId());
//System.out.println(finalIndex + " "+ Thread.currentThread().getName() + " " + snowflakeDemo.getId());
snowflakeDemo.getId();
} catch (Exception e) {
}
}
};
pool.execute(run);
}
System.out.println("[1] done!");
pool.shutdown();
}
//模拟并发
public void m2() {
SnowflakeDemo snowflakeWorker0 = new SnowflakeDemo(System.currentTimeMillis(), 0, 0);
ExecutorService executorService = Executors.newCachedThreadPool();
//信号量,此处用于控制并发的线程数
final Semaphore semaphore = new Semaphore(threadTotal);
//闭锁,可实现计数器递减
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
//执行此方法用于获取执行许可,当总计未释放的许可数不超过200时,
//允许通行,否则线程阻塞等待,直到获取到许可。
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + ": " + snowflakeWorker0.getId());
//释放许可
semaphore.release();
} catch (Exception e) {
//log.error("exception", e);
e.printStackTrace();
}
//闭锁减一
countDownLatch.countDown();
});
}
try {
countDownLatch.await();//线程阻塞,直到闭锁值为0时,阻塞才释放,继续往下执行
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.shutdown();
}
public static void main(String[] args) {
long bt = System.currentTimeMillis();
SnowflakeDemo snowflakeWorker0 = new SnowflakeDemo(bt, 0, 0);
for(int i = 0; i < loopNum; i++) {
System.out.println(snowflakeWorker0.getId());
/*for(int i = 0; i < loopNum; i++) {
snowflakeWorker0.getId();
}
long et = System.currentTimeMillis();
long et2 = System.currentTimeMillis();
System.out.println("耗时:"+(et2 - bt)+ "ms");
System.out.println("吞吐量为:"+loopNum*1.0/(et - bt));
System.out.println("吞吐量为:"+loopNum*1.0/(et2 - bt));*/
/*SnowflakeDemo TestThreadPool = new SnowflakeDemo();
long bt = System.currentTimeMillis();
SnowflakeDemo TestThreadPool = new SnowflakeDemo();
TestThreadPool.m1();
//TestThreadPool.m2();
long et2 = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("耗时:"+(et2 - bt)+ "ms");
System.out.println("吞吐量为:"+loopNum*1.0/(et2 - bt));*/
System.out.println("吞吐量为:"+loopNum*1.0/(et2 - bt));
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论