我需要一个字节生成器,它将生成从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 – 这个线程安全的字节序列生成器有什么问题?相关推荐

  1. java字节数_Java各种类型占用的字节数

    数据类型 大小(二进制位数) 范围 默认值 byte(字节) 8 -128 - 127 0 shot(短整型) 16 -32768 - 32768 0 int(整型) 32 -2147483648-2 ...

  2. java 字符类型 字节数_JAVA基本数据类型所占字节数是多少?

    byte     1字节 short    2字节 int      4字节 long     8字节 char     2字节(C语言中是1字节)可以存储一个汉字 float    4字节 doub ...

  3. java 添加等待时间_Java中线程等待特定时间的最有效方法 - java

    我知道这个问题here,但是我有一个稍微不同的问题.如果我希望自己通过各种Thread方法(而不是通过实用程序类或Quartz)手动编码某个线程在特定时间的运行,那么最有效(就开销而言)进行编码. 我 ...

  4. java inputstream长度_Java InputStream.available获取数据流字节长度大小

    首页 > 基础教程 > IO流 > InputStream类 Java InputStream.available获取数据流字节长度大小 定义 public int availabl ...

  5. java singleton 多线程_Java创建线程安全的单例singleton

    Java创建线程安全的单例 单例的使用场景 JVM中仅需要一个实例,因此能节省内存,加快访问速度,比如数据库连接池,计数器等.Spring 中的Bean,默认也是单例的,共享资源的访问,比如日志文件, ...

  6. java阻塞超时_JAVA防线程阻塞(超时控制)

    2.[代码]TimeoutThread /** * java线程超时控制的实现 * * 超时控制一般使用阻塞时间比较长的操作上,有可能是和远程数据库的连接,也有可能是网络下载,在程序超时后, 往往需要 ...

  7. java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程

    最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...

  8. java释放锁_java – 一个线程在完成后释放锁吗?

    简单测试可能会显示在线程终止时未释放锁定: import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock ...

  9. java多线程通信_Java多线程-线程通信

    原标题:Java多线程-线程通信 通信的方式 要想实现多个线程之间的协同,如:线程执行先后顺序.获取某个线程执行的结果等等.涉及到线程之间的相互通信,分为下面四类: 文件共享 网络共享 共享变量 JD ...

最新文章

  1. 10上wsl位置迁移_wsl的安装/升级笔记
  2. Java黑皮书课后题第8章:***8.35(最大块)给定一个元素为0或者1的方阵,编写程序,找到一个元素都为1的最大的子方阵。程序提示用户输入矩阵的行数。然后显示最大的子方阵的第一个元素、行数
  3. 一个架构的演化2--用ESB集成
  4. 4.1-大秦立国-ip演变
  5. 人工智障学习笔记——梯度下降(1)基础变种
  6. 工厂供电MATLAB仿真,工厂供电课程设计---基于MATLAB的电力电子系统仿真
  7. Kite Compositor for Mac基本工具的使用教程
  8. struts2——快速入门
  9. Nacos集群(二)阿里自研弱一致性Distro协议核心实现
  10. 服务器配置文档模板,服务器配置模板
  11. 图像和视频语义分割的深度学习技术综述
  12. 网页连接服务器数据库,网站程序中常见的数据库连接方法
  13. DB2新建用户及数据库过程
  14. Python的exec
  15. uiautomatorviewer 工具使用
  16. 书单|互联网企业面试案头书之程序员软技能篇
  17. 学生实验室常见升压降压芯片电路介绍
  18. 单枪匹马想要搞定亿级流量?2021阿里都换成这个牛逼架构了
  19. datastage transformer控件详解
  20. html 文本转语音,百度文字转语音免费接口使用实例

热门文章

  1. Dotnet Core多版本API共存的优雅实现
  2. IdentityServer4系列 | 授权码模式
  3. Docker Vs Podman
  4. 微软发布VS Code Jupyter插件!不止Python!多语言的Jupyter Notebook支持来了!
  5. 《ASP.NET Core项目开发实战入门》送书活动结果公布
  6. (译)An introduction to Kubernetes
  7. .Net开发3年,应聘大厂惨遭淘汰,如何翻身打脸面试官?
  8. C# 8 新特性 - 异步流 Asynchronous Streams
  9. .netcore 开发的 iNeuOS 物联网平台部署在 Ubuntu 操作系统,无缝跨平台
  10. 书籍推荐:《More Effective C#》