avatar

Catalog
java线程同步

1.多线程的问题

当多个线程同时运行时,线程的调度由操作系统决定,程序本身无法决定。因此,任何一个线程都有可能在任何指令处被操作系统暂停,然后在某个时间段后继续执行。

这个时候,有个单线程模型下不存在的问题就来了:如果多个线程同时读写共享变量,会出现数据不一致的问题。

2.注意

当对共享变量进行写入时,必须保证时原子操作

原子操作时指不能被中断的一个或一系列操作

当进行加操作时

n=n+1 =====> 对应的字节码指令,ILOAD , IADD, ISTORE不是原子操作

当线程A执行了ILOAD后,如果有其他线程执行了ISTORE操作,将原值改变了,但是线程A无法知道。所以就出现了问题

3.解决方法

synchronized

synchronized保证了代码块再任意时刻只能有一个线程执行:

问题 因为无法并发,所以会下降,加锁和解锁也会消耗时间

使用

  1. 找出修改共享变量的线程代码块
  2. 选择一个实例作为锁
  3. 使用synchronized(lockObject){…}

JVM规范的原子操作

基本类型赋值(long 和double):

int n = 100;

引用类型赋值

List list = anotherList;

总结

多线程同时修改变量,出现逻辑错误

  • 需要synchronized同步
  • 同步本质就是给指定对象加锁
  • 加锁必须是同一个实例

对jvm定义的单个原子操作

二、synchronized锁住方法

  • 用synchronized修饰方法可以把整个方法变为同步代码块
  • synchronized方法加锁对象是this
  • 通过合理的设计和数据封装可以让一个类变为“线程安全”
  • 一个类没有特殊说明,默认不是thread-safe
  • 多线程能否访问某个非线程安全的实例,需要具体问题具体分析
Author: kim yhow
Link: http://yoursite.com/2020/08/08/java线程同步/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶