关于并发,首先我们要了解一些它的基础概念:
1. 进程和线程的基础概念:
进程:进程可以被视为程序的一个实例,大部分程序可以有多个实例进程。当从磁盘加载一个程序的代码到内存,这就开启了一个进程。
进程是资源分配的最小单位;
进程是相互独立的;
进程间的通信:同一计算机:IPC;不同计算机:通过网络如HTTP;(标记IPC)
线程:一个进程中可以分为一到多个线程,一个线程就是一个指令流,将指令流中的一条条指令交给CPU执行。
线程是操作系统在CPU调度时的最小单位;
线程相互不独立;
线程间的通信:共享进程内的内存;
2. 并发和并行的基础概念
并发&java并发基础介绍#xff1a;单核工作,不同线程轮流使用CPU时间片,在同一时间段内交替进行;
并行:多核工作,不同线程同时使用不同CPU,在同一时刻真正同时运行;
3. 同步与异步的基础概念:
同步:在同步操作中,任务必须等待上一个任务完成,才能继续执行下一个任务。
异步:在异步操作中,任务可以在未等待前一个任务完成的情况下继续执行。
4.阻塞与非阻塞的基础概念:
阻塞:线程原地等待,直到某个条件满足(如等待I/O操作完成)。
非阻塞:线程不会等待,可以立即返回并继续执行其他任务。
5.悲观锁和乐观锁的基础概念:
悲观锁:悲观锁主动加锁,确保其他线程无法并发修改该资源。这种策略会使得在锁持有期间,其他线程对资源的读写操作被阻塞,直到锁被释放。
悲观锁常用于高并发、修改频繁的场景,以避免数据不一致问题;
乐观锁:乐观锁不主动加锁。在更新资源时会进行冲突检测(版本号或时间戳)。如果检测到在当前线程读取数据后有其他线程修改了数据,那么更新操作会被拒绝,但线程不会阻塞。
乐观锁适用于读操作频繁、写操作较少的场景。它通过允许并发读取、提高了系统的并发性;
6.线程安全的基础概念:多个线程访问共享数据时,不会出现数据竞争问题。
常见的线程安全机制包括锁(、)、原子操作类(等);
7.上下文切换的基础概念:当操作系统在不同线程之间切换时,保存一个线程的状态并加载另一个线程的状态的过程。
频繁的上下文切换会导致性能开销;
8.临界区的基础概念:临界区是指一个线程访问共享资源的代码段。
多个线程不能同时进入临界区,否则会导致数据不一致;
9.volatile的基础概念:关键字可以确保变量对所有线程的可见性。
可见性问题是指当一个线程修改了共享变量时,其他线程可能不会立即看到这个变化;
在了解基础概念后,我们再来了解一些基础的代码。
1.如何创建一个线程?
第一种方法:继承Thread类
优点:简单明了,直接创建一个线程对象。
缺点:继承了 类就不能再继承其他类;任务和线程直接耦合,不够灵活。
Thread t = new Thread(“t1”){
@Override
public void run() {
// 执行代码
}
};
t.start();
第二种方法:实现Runnable接口(推荐)
优点:灵活,Runnable只是一个任务,可以与线程分开管理。
缺点:代码上稍微比直接继承Thread更复杂一些。
Runnable r = () -> {
// 执行代码
};
Thread t = new Thread(r);
t.start();
第三种方法:实现Callable接口
如果你的任务不需要返回值,并且你也不关心任务的结果,可以使用 。
如果你需要返回任务的结果,比如执行完后获得计算结果、网络请求响应等, 和 是非常适合的选择。
FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// 执行代码
}
});
Thread t = new Thread(task);
t.start();
以下是一些Thread类的常见方法:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/2507.html