"JUC并发编程学习笔记,主要涵盖了Java并发编程的基础概念和JUC包中的相关工具类。"
在Java编程中,JUC(Java Util Concurrency)是Java并发编程的核心工具包,提供了高级并发构建块,使得开发者能够编写更加高效、安全的多线程程序。JUC包含了许多类和接口,用于简化线程同步、线程池管理、并发容器以及原子变量等并发操作。
## 一、什么是JUC?
JUC全称为Java Util Concurrency,它是Java标准库中的一个包,主要用于提高多线程环境下的程序性能和可维护性。JUC提供了一系列的并发工具类,如`ExecutorService`、`Semaphore`、`CountDownLatch`、`CyclicBarrier`、`Future`和`CompletableFuture`等,这些工具类可以帮助开发者更好地管理和控制并发执行的任务,减少锁的使用,避免死锁和竞态条件等问题。
在传统的并发编程中,我们通常使用`Thread`类或实现`Runnable`接口来创建和启动线程。`Thread`类代表一个可执行的线程,而`Runnable`接口定义了一个无返回值的任务。然而,这种方式有时效率较低,因为它无法直接返回结果。相比之下,`Callable`接口允许我们创建有返回值的线程任务,但Java中直接通过`Thread`启动的线程不支持`Callable`。
## 二、线程与进程
### 进程
- 进程是操作系统分配资源的基本单位,它是一个程序的运行实例,比如QQ.exe就是一个进程。
- 每个进程都有一组线程,至少包含一个主线程。在Java中,除了用户创建的线程外,还有垃圾回收线程(GC线程)等系统线程。
- 类比来说,一个部门可以看作是一个进程,部门中的员工则代表线程,部门共同完成一项工作,而员工可以单独或协作完成各自的任务。
### 线程
- Java中创建线程主要有三种方式:
1. 直接继承`Thread`类并重写`run()`方法。
2. 实现`Runnable`接口并提供`run()`方法,然后通过`Thread`类的构造函数创建线程。
3. 实现`Callable`接口并提供`call()`方法,使用`FutureTask`包装后创建线程。
Java虚拟机(JVM)实际上并不能真正地创建线程,而是依赖于底层操作系统来创建和调度线程。当调用`Thread.start()`方法时,JVM会与操作系统进行交互,请求创建一个新的线程来执行任务。
```java
public synchronized void start() {
// ...
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0(); // 这是一个native方法,交由操作系统处理
} catch (Throwable t) {
group.uncaughtException(this, t);
}
if (!started)
group.threadStartFailed(this);
}
```
`Thread.start()`方法内部调用了`start0()`,这是一个本地(native)方法,意味着它的实现是在操作系统层面,JVM通过这个方法向操作系统发出请求来创建和启动线程。
JUC包的出现,极大地提高了Java并发编程的便利性和安全性,使得开发者能更专注于业务逻辑,而不是底层并发细节,从而编写出更健壮的并发应用。在实际开发中,熟练掌握JUC工具类的应用,对于提升程序性能和降低并发问题的出现至关重要。