java 字节序列_java – 这个线程安全的字节序列生成器有什么问题?
我需要一个字节生成器,它将生成从Byte.MIN_VALUE到Byte.MAX_VALUE的值.当它达到MAX_VALUE时,它应该从MIN_VALUE重新开始.
我使用AtomicInteger编写了代码(见下文);但是,如果同时访问并且如果使用Thread.sleep()人为地减慢了代码,那么代码似乎没有正常运行(如果没有睡眠,它运行正常;但是,我怀疑它对于出现并发问题来说太快了).
代码(添加了一些调试代码):
public class ByteGenerator {
private static final int INITIAL_VALUE = Byte.MIN_VALUE-1;
private AtomicInteger counter = new AtomicInteger(INITIAL_VALUE);
private AtomicInteger resetCounter = new AtomicInteger(0);
private boolean isSlow = false;
private long startTime;
public byte nextValue() {
int next = counter.incrementAndGet();
//if (isSlow) slowDown(5);
if (next > Byte.MAX_VALUE) {
synchronized(counter) {
int i = counter.get();
//if value is still larger than max byte value,we reset it
if (i > Byte.MAX_VALUE) {
counter.set(INITIAL_VALUE);
resetCounter.incrementAndGet();
if (isSlow) slowDownAndLog(10,"resetting");
} else {
if (isSlow) slowDownAndLog(1,"missed");
}
next = counter.incrementAndGet();
}
}
return (byte) next;
}
private void slowDown(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
}
}
private void slowDownAndLog(long millis,String msg) {
slowDown(millis);
System.out.println(resetCounter + " "
+ (System.currentTimeMillis()-startTime) + " "
+ Thread.currentThread().getName() + ": " + msg);
}
public void setSlow(boolean isSlow) {
this.isSlow = isSlow;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
}
并且,测试:
public class ByteGeneratorTest {
@Test
public void testGenerate() throws Exception {
ByteGenerator g = new ByteGenerator();
for (int n = 0; n < 10; n++) {
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
assertEquals(i,g.nextValue());
}
}
}
@Test
public void testGenerateMultiThreaded() throws Exception {
final ByteGenerator g = new ByteGenerator();
g.setSlow(true);
final AtomicInteger[] counters = new AtomicInteger[Byte.MAX_VALUE-Byte.MIN_VALUE+1];
for (int i = 0; i < counters.length; i++) {
counters[i] = new AtomicInteger(0);
}
Thread[] threads = new Thread[100];
final CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
try {
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
byte value = g.nextValue();
counters[value-Byte.MIN_VALUE].incrementAndGet();
}
} finally {
latch.countDown();
}
}
},"generator-client-" + i);
threads[i].setDaemon(true);
}
g.setStartTime(System.currentTimeMillis());
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
latch.await();
for (int i = 0; i < counters.length; i++) {
System.out.println("value #" + (i+Byte.MIN_VALUE) + ": " + counters[i].get());
}
//print out the number of hits for each value
for (int i = 0; i < counters.length; i++) {
assertEquals("value #" + (i+Byte.MIN_VALUE),threads.length,counters[i].get());
}
}
}
在我的2核机器上的结果是值#-128得到146次点击(所有这些都应该得到100次点击,因为我们有100个线程).
如果有人有任何想法,这个代码有什么问题,我都是耳朵/眼睛.
更新:对于那些赶时间并且不想向下滚动的人来说,在Java中解决这个问题的正确(以及最短和最优雅)方式将是这样的:
public byte nextValue() {
return (byte) counter.incrementAndGet();
}
谢谢,亨氏!
java 字节序列_java – 这个线程安全的字节序列生成器有什么问题?相关推荐
- java字节数_Java各种类型占用的字节数
数据类型 大小(二进制位数) 范围 默认值 byte(字节) 8 -128 - 127 0 shot(短整型) 16 -32768 - 32768 0 int(整型) 32 -2147483648-2 ...
- java 字符类型 字节数_JAVA基本数据类型所占字节数是多少?
byte 1字节 short 2字节 int 4字节 long 8字节 char 2字节(C语言中是1字节)可以存储一个汉字 float 4字节 doub ...
- java 添加等待时间_Java中线程等待特定时间的最有效方法 - java
我知道这个问题here,但是我有一个稍微不同的问题.如果我希望自己通过各种Thread方法(而不是通过实用程序类或Quartz)手动编码某个线程在特定时间的运行,那么最有效(就开销而言)进行编码. 我 ...
- java inputstream长度_Java InputStream.available获取数据流字节长度大小
首页 > 基础教程 > IO流 > InputStream类 Java InputStream.available获取数据流字节长度大小 定义 public int availabl ...
- java singleton 多线程_Java创建线程安全的单例singleton
Java创建线程安全的单例 单例的使用场景 JVM中仅需要一个实例,因此能节省内存,加快访问速度,比如数据库连接池,计数器等.Spring 中的Bean,默认也是单例的,共享资源的访问,比如日志文件, ...
- java阻塞超时_JAVA防线程阻塞(超时控制)
2.[代码]TimeoutThread /** * java线程超时控制的实现 * * 超时控制一般使用阻塞时间比较长的操作上,有可能是和远程数据库的连接,也有可能是网络下载,在程序超时后, 往往需要 ...
- java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程
最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...
- java释放锁_java – 一个线程在完成后释放锁吗?
简单测试可能会显示在线程终止时未释放锁定: import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock ...
- java多线程通信_Java多线程-线程通信
原标题:Java多线程-线程通信 通信的方式 要想实现多个线程之间的协同,如:线程执行先后顺序.获取某个线程执行的结果等等.涉及到线程之间的相互通信,分为下面四类: 文件共享 网络共享 共享变量 JD ...
最新文章
- 10上wsl位置迁移_wsl的安装/升级笔记
- Java黑皮书课后题第8章:***8.35(最大块)给定一个元素为0或者1的方阵,编写程序,找到一个元素都为1的最大的子方阵。程序提示用户输入矩阵的行数。然后显示最大的子方阵的第一个元素、行数
- 一个架构的演化2--用ESB集成
- 4.1-大秦立国-ip演变
- 人工智障学习笔记——梯度下降(1)基础变种
- 工厂供电MATLAB仿真,工厂供电课程设计---基于MATLAB的电力电子系统仿真
- Kite Compositor for Mac基本工具的使用教程
- struts2——快速入门
- Nacos集群(二)阿里自研弱一致性Distro协议核心实现
- 服务器配置文档模板,服务器配置模板
- 图像和视频语义分割的深度学习技术综述
- 网页连接服务器数据库,网站程序中常见的数据库连接方法
- DB2新建用户及数据库过程
- Python的exec
- uiautomatorviewer 工具使用
- 书单|互联网企业面试案头书之程序员软技能篇
- 学生实验室常见升压降压芯片电路介绍
- 单枪匹马想要搞定亿级流量?2021阿里都换成这个牛逼架构了
- datastage transformer控件详解
- html 文本转语音,百度文字转语音免费接口使用实例
热门文章
- Dotnet Core多版本API共存的优雅实现
- IdentityServer4系列 | 授权码模式
- Docker Vs Podman
- 微软发布VS Code Jupyter插件!不止Python!多语言的Jupyter Notebook支持来了!
- 《ASP.NET Core项目开发实战入门》送书活动结果公布
- (译)An introduction to Kubernetes
- .Net开发3年,应聘大厂惨遭淘汰,如何翻身打脸面试官?
- C# 8 新特性 - 异步流 Asynchronous Streams
- .netcore 开发的 iNeuOS 物联网平台部署在 Ubuntu 操作系统,无缝跨平台
- 书籍推荐:《More Effective C#》