原子性(Atomicity)
原子性是指一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。在并发编程中,原子性是一个关键概念,因为它确保了数据的一致性和线程安全。
例如,假设有一个银行账户余额的变量,两个线程分别尝试对其进行增加操作。如果没有原子性的保证,一个线程可能在读取余额、计算新余额和写回新余额的过程中被另一个线程打断,导致数据不一致。通过使用原子操作(例如,通过synchronized
关键字或java.util.concurrent.atomic
包中的原子类),可以确保这些操作作为一个不可分割的单元来执行,从而避免了不一致性。
可见性(Visibility)
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值。在并发编程中,由于JVM的优化和CPU的缓存机制,一个线程对共享变量的修改可能不会立即对其他线程可见。这就是所谓的“可见性问题”。
为了确保可见性,Java提供了volatile
关键字。当一个变量被声明为volatile
时,JVM会保证所有线程看到这个变量的值是一致的。当一个线程修改了一个volatile
变量的值,这个修改会立即同步到主内存,当有其他线程需要读取这个变量时,它会去主内存中读取新值。
有序性(Ordering)
有序性是指程序执行的顺序按照代码的先后顺序执行。在单线程环境中,这通常是自然的,因为代码是按照顺序一行一行执行的。然而,在并发环境中,由于JVM和CPU的优化,指令的执行顺序可能会与代码中的顺序不同。
为了确保有序性,Java提供了volatile
关键字和synchronized
关键字。volatile
关键字会禁止指令重排,确保对volatile
变量的操作按照预期的顺序执行。而synchronized
关键字则提供了一种互斥锁的机制,确保同一时间只有一个线程能够访问共享变量,从而避免了指令重排带来的问题。