java 多线程读取有状态对象_为什么多线程环境不适合带有状态的对象?

一、为什么多线程环境不适合带有状态的对象?

这个问题更清晰一点是“在共享内存模型下,为什么多线程环境不适合带有状态的共享对象”,如果对象不贡献,是线程私有的,或者压根就不是共享内存,带状态都无所谓的。 但是一旦需要共享,由于多线程在执行对象方法修改状态时会在任意时间执行任意指令,导致程序的顺序性无法保证,造成bug。举个多线程入门都会知道的例子:

假设有一个计数的对象counter,类定义如下:

这个counter是多线程的共享对象,其中的getAndIncrement在各个线程里面实际执行的序列是:

long temp = value;

value = temp + 1;

return temp;每个thread都会去内存读取value然后在thread本地处理并写回,问题在于在一个thread执行这个sequence时,其他线程可能已经执行很多次了,假设value都已经变成4了,但是这个thread在读的时候还是1,这样一来写回2,把其他线程的结果都覆盖了,出现bug。问题的本质是这个读value,+1然后写回的操作sequence对于共享变量有大于1个的操作(这里是读写)且不是原子性的,也就是会有很多threads插入交织在任意时间执行任何一个step。

带状态的对象天然不是多线程安全的,应该能够说明这个问题了。

二、是不是意味着如果有多线程环境,最好慎用面向对象编程?

多线程环境下,只要是内存共享可修改的状态,无论什么范式都是一样的问题,跟是否面向对象无关。问题的关键在于多线程算是打破了对于cpu,内存的抽象,需要你对这些东西有一定的了解,才能写出线程安全且高效的程序,虽说常用的面向对象语言都自带了并发包,但也不是一股脑地加锁互斥同步就算的上OK,除了性能之外,还有死锁,饥饿等问题。

函数式编程以及某些并发模型,对写多线程程序是友好的,

三、自定义对象能否作为数据包传递从服务器到客户端?

可以,一般中间会有serDe,比如Json, xml, byte,hessian, pb等。

四、如果真的是这样,ooad时要考虑哪些方面呢?

并发问题跟你说的面向对象设计,java web,数据传输是不同层次的东西。有疑问的时候,一定要定位到问题是什么,对于你这几个问题,定位到你对并发是没有概念的,作为学生,你就可以去学习并发编程设计,写代码,验证(学的过程中自然会接触到相关的知识)。还有一个,问题里面提到了很多次面向对象设计,但凡是设计一定是有原则,以及基于这个原则下好的实践的总结(模式),锻炼自己面向对象设计能力时可以借鉴一下,有帮助。不过这些东西有一个共同的特点:不写点垃圾代码,感受不深:D。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值