我对

Scala和函数式编程比较陌生,我喜欢使用不可变对象的想法,我可以避免许多线程安全陷阱.有一件事仍然困扰着我,这是用于教授线程安全的经典示例 – 共享计数器.

我想知道是否可以实现线程安全计数器(在此示例中为请求计数器),使用不可变对象和功能概念,并完全避免同步.

所以在这里参考首先是计数器的经典可变版本

(请原谅我的公共成员变量,仅为了简洁示例)

可变,非线程安全版本:

public class Servlet extends HttpServlet {

public int requestCount = 0;

@Override

public void service(ServletRequest req,ServletResponse res) throws ... {

requestCount++; //thread unsafe

super.service(req,res);

}

}

可变,经典的线程安全版本:(或者我希望…)

public class Servlet extends HttpServlet {

public volatile int requestCount = 0;

@Override

public void service(ServletRequest req,ServletResponse res) throws ... {

synchronized (this) {

requestCount++;

}

super.service(req,res);

}

}

我想知道是否有一种方法使用不可变对象和volatile变量来实现线程安全而不需要同步.

所以这是我天真的尝试.我们的想法是为计数器提供一个不可变对象,并使用volatile变量替换对它的引用.感觉很腥,但值得一试.

持有人:

public class Incrementer {

private final int value;

public Incrementer(final int oldValue) {

this.value = oldValue + 1;

}

public Incrementer() {

this.value = 0;

}

public int getValue() {

return value;

}

}

修改后的servlet:

public class Servlet extends HttpServlet {

public volatile Incrementer incrementer = new Incrementer();

@Override

public void service(ServletRequest req,ServletResponse res) throws ... {

incrementer = new Incrementer(incrementer.getValue());

super.service(req,res);

}

}

我有一种强烈的感觉,这也不是线程安全的,因为我从增量器读取,并且可能得到一个陈旧的值(例如,如果引用已经被另一个线程替换).如果它确实不是线程安全的,那么我想知道是否存在任何“功能”方式来处理这种没有锁定/同步的计数器场景.

所以我的问题是

>这个线程是否安全?

>如果是,为什么?

>如果没有,是否有任何方法可以在没有同步的情况下实现这样的计数器?

虽然上面的示例代码是用Java编写的,但Scala中的回复当然也是受欢迎的

java 线程安全 计数_java – 实现线程安全共享计数器的功能方法相关推荐

  1. JAVA线程六种状态_Java:线程的六种状态及转化

    多线程概述及创建方式 Java:线程的六种状态及转化 关于线程的生命周期,网上书上说法不一,难以统一,本篇做一个总结: java.lang.Thread.State枚举类中定义了六种线程的状态,可以调 ...

  2. java线程中等待_Java:线程中的Thread.sleep():没有等待

    线程没有睡觉我有问题. 我不能把我的整个代码放在这里.所以,为了重现,这里是一个等待5秒的基本代码. try { int millisec = 5000; System.out.println(new ...

  3. java daemon线程的作用_JAVA DAEMON线程的理解

    java线程分两种:用户线程和daemon线程.daemon线程或进程就是守护线程或者进程,但是java中所说的daemon线程和linux中的daemon是有一点区别的. linux中的daemon ...

  4. java 编写线程公共类_Java实现线程间通信方式

    线程间通信的模型: 共享内存 消息传递 我们来做道题理解一下 题目: 有两个线程A.B,A线程向一个集合里面依次添加元素"abc"字符串,一共添加十次,当添加到第五次的时候,希望B ...

  5. java创建线程并命名_Java创建线程的两种方式

    前言 多线程是我们开发过程中经常遇到的,也是必不可少需要掌握的.当我们知道需要进行多线程开发时首先需要知道的自然是如何实现多线程,也就是我们应该如何创建线程. 在Java中创建线程和创建普通的类的对象 ...

  6. java线程通信概念_java基础线程总结(线程概念、线程创建方式、线程间通信、线程重要方法)...

    基础篇之<线程> @author :kern ---------------------------------------------------------------- 一:进程:是 ...

  7. java多线程 修改优先级_Java多线程-线程的调度(优先级)

    与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...

  8. java线程交替执行_Java synchronized线程交替运行实现过程详解

    背景 用两个线程交替输出A-Z和1-26,即一个线程输出A-Z,另一个线程输出1-26 而且是交替形式 线程1输出A--线程二输出1 线程1输出B--线程二输出2 线程1输出C--线程二输出3 以此类 ...

  9. java线程池面试题_java之线程池面试题

    面试官:线程池有哪些?分别的作用是什么? 常用的线程池有: newSingleThreadExecutor newFixedThreadExecutor newCacheThreadExecutor ...

最新文章

  1. 高性能IO设计中的Reactor模式与Proactor模式
  2. 诺奖得主涉嫌学术不端!30余篇论文被指涉嫌P图造假、复制粘贴,合作者包括中国学者...
  3. 中国程序员超 5000 万?北上广等一线城市 IT 岗位已开始饱和过剩?
  4. RMB77元实现全身VR跟踪,来自配合微软Kinect的Driver4VR
  5. idea 两次运行同一main方法 开启两个进程
  6. python函数使用易错点_Python易错例题
  7. ctrl导致开机弹出计算机,Win7系统开机黑屏提示Press Ctrl+Alt+Del to restart如何解决...
  8. java 线程简介_java多线程介绍
  9. ChaiNext:过去24小时,市场情绪“燥”
  10. java集合了类面试题_一些集合类面试题,说不定你就会遇到
  11. Java写入磁盘阵列_什么是RAID?RAID有什么用?RAID原理
  12. matlab prn文件,教你妙用PRN文件 实现文档的换机打印
  13. 我的随身电脑-千脑(转载)
  14. VB.NET 强制删除文件
  15. 关于vue路由模式导致微信jssdk授权问题的正确解决姿势
  16. 车站安防巡逻机器人未来发展趋势是什么?
  17. android 开发社区
  18. 五年级计算机课总结,2015秋信息技术五年级上册工作总结
  19. 网易Airtest简介
  20. 一文彻底说明分布式事务原理

热门文章

  1. Spring学习总结(8)——25个经典的Spring面试问答
  2. Blockathon记录——by 参赛者 张翔
  3. 转://工作中 Oracle 常用数据字典集锦
  4. 恢复到特定点(时间点、scn、日志序列号),rman不完全恢复
  5. 基于Starling的mask实现
  6. 精品素材 – 24款扁平风格 PSD 格式图标免费下载
  7. Domino服务器以及Notes客户端重新配置的方法
  8. 关于Object数组强转成Integer数组的问题:Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;...
  9. 第76节:Java中的基础知识
  10. xadmin与admin设置