Java并发编程是Java中处理多个任务同时执行的能力。在构建高性能、可扩展和响应性良好的系统时,并发编程是非常关键的。以下是Java并发编程中的一些基础概念:
-
线程(Thread):
- 线程是操作系统调度的最小单位,是程序执行流的最小单元。
- 在Java中,每个线程都有一个执行栈,用于存储局部变量和调用栈信息。
- 线程共享进程的资源,如内存空间、文件句柄等。
-
进程(Process):
- 进程是操作系统分配资源的基本单位,它包含了一个或多个线程、系统资源(如内存空间、文件句柄等)以及程序计数器、寄存器等信息。
- 在Java中,通常一个JVM实例就是一个进程。
-
并发(Concurrency):
- 并发指的是多个任务在同一时间段内交替执行,宏观上看起来是同时进行的。
- Java通过线程来实现并发编程。
-
并行(Parallelism):
- 并行指的是多个任务在同一时刻同时执行,这通常依赖于多核CPU或分布式系统。
- 在Java中,可以通过创建多个线程并利用多核CPU来实现并行处理。
-
同步(Synchronization):
- 同步是一种避免多个线程同时访问共享资源并造成数据不一致的机制。
- Java提供了多种同步机制,如
synchronized
关键字、ReentrantLock
等。
-
异步(Asynchrony):
- 异步编程是一种处理并发问题的策略,它允许一个任务的执行不依赖于前一个任务的完成。
- 在Java中,可以使用
CompletableFuture
、Future
和Callback
等来实现异步编程。
-
死锁(Deadlock):
- 死锁是两个或更多的线程因为竞争资源而造成的一种状态,每个线程都在等待其他线程释放资源,导致所有线程都无法继续执行。
- 避免死锁的方法包括使用超时等待、设置锁的顺序等。
-
活锁(Livelock):
- 活锁是指线程之间不断争夺资源,但都没有成功执行,导致系统看起来在“忙碌”但实际上没有进展。
- 避免活锁的方法包括使用退避策略、优先级策略等。
-
饥饿(Starvation):
- 饥饿是指某个或某些线程因为得不到资源而无法继续执行。
- 避免饥饿的方法包括设置优先级、确保公平性等。
-
线程安全(Thread-safe):
- 线程安全是指多个线程同时访问一个对象时,对象的各个状态都保持正确。
- 实现线程安全的方法包括不可变对象、同步方法、同步块、原子类等。
-
原子性(Atomicity):
- 原子性是指一个操作或多个操作要么全部执行,要么全部不执行,不会在中间状态被其他线程打断。
- Java中的
java.util.concurrent.atomic
包提供了原子类来实现原子操作。
-
可见性(Visibility):
- 可见性是指当一个线程修改了共享变量的值后,其他线程能够立即看到这个修改。
- Java通过
volatile
关键字和synchronized
关键字来保证可见性。
-
有序性(Ordering):
- 有序性是指程序执行的顺序按照代码的先后顺序执行。
- 但是由于编译器优化和CPU指令重排等因素,实际执行的顺序可能与代码顺序不一致。
- Java通过
volatile
关键字和synchronized
关键字以及Happens-Before
规则来保证有序性。