对多线程原子性的理解
多线程原子性的理解:一个操作要么全部执行完毕,不会受到干扰而被中断;要么全都不执行
- 对于多线程中操作共享变量的操作,要保证它的原子性。
- 以下是对一个非原子性操作的分析:
- 在一个类中有共享变量count,开启一百个线程对其进行count++操作,每个线程对count加一百次。
- count变量是属于共享变量,在每个线程操作它的时候,需要先把它读取到自己的工作内存中。
- 如果说A线程读取了count,这时候cpu分配了时间片给B线程,B线程也读取到了count,并且进行了count++操作,但是还没有写回主内存。
- 这时候cpu分配时间片给A线程,它进行count++操作,同时写会主内存,又分配给线程B,同时将操作写会主线程。
- 这就属于线程A的操作被线程B干扰而中断,最终导致count只被修改了一次,并没有确保原子性。
为什么volatile不能保证原子性呢
对volatile机制解释
- 被volatile修饰的变量account。如果说线程A对account进行了修改,并且将该数据写回了主内存,那么会使得其他线程工作内存中的account关键字失效。
- 如果其他线程需要操作该count,那么会再次从主内存中拿到自己的工作内存中。这样就解决了共享变量的可见性。
回归正题
- 对于像上面那个非原子性操作count的例子中:A读取到了count,B读取到了count并修改,但是没写回。
- 然后又到线程A,A执行了修改并且写会。这时候又到B线程,但是B此时已经不需要再对count操作了
- 不对共享变量操作,那么不会再去主内存中读值再操作。也就是B线程会直将数据写会到主内存。也就是说volatile无法保证原子性。
而对于synchronized
- 它可以保证原子性,因为只有拿到锁的线程可以操作共享变量count,而其他线程会被阻塞。保证了当前线程不会收到干扰而中断。