1.多线程的问题
当多个线程同时运行时,线程的调度由操作系统决定,程序本身无法决定。因此,任何一个线程都有可能在任何指令处被操作系统暂停,然后在某个时间段后继续执行。
这个时候,有个单线程模型下不存在的问题就来了:如果多个线程同时读写共享变量,会出现数据不一致的问题。
2.注意
当对共享变量进行写入时,必须保证时原子操作
原子操作时指不能被中断的一个或一系列操作
当进行加操作时
n=n+1 =====> 对应的字节码指令,ILOAD , IADD, ISTORE不是原子操作
当线程A执行了ILOAD后,如果有其他线程执行了ISTORE操作,将原值改变了,但是线程A无法知道。所以就出现了问题
3.解决方法
synchronized
synchronized保证了代码块再任意时刻只能有一个线程执行:
问题 因为无法并发,所以会下降,加锁和解锁也会消耗时间
使用
- 找出修改共享变量的线程代码块
- 选择一个实例作为锁
- 使用synchronized(lockObject){…}
JVM规范的原子操作
基本类型赋值(long 和double):
int n = 100;
引用类型赋值
List
总结
多线程同时修改变量,出现逻辑错误
- 需要synchronized同步
- 同步本质就是给指定对象加锁
- 加锁必须是同一个实例
对jvm定义的单个原子操作
二、synchronized锁住方法
- 用synchronized修饰方法可以把整个方法变为同步代码块
- synchronized方法加锁对象是this
- 通过合理的设计和数据封装可以让一个类变为“线程安全”
- 一个类没有特殊说明,默认不是thread-safe
- 多线程能否访问某个非线程安全的实例,需要具体问题具体分析




