多线程知识梳理

 进程、线程、管程、协程

进程 (Process)

进程是操作系统分配资源的基本单位。每个进程都有自己的内存空间、文件描述符、堆栈等资源。

进程的特点

独立性:进程之间是独立的,互不干扰。一个进程的崩溃不会影响其他进程。

资源丰富:每个进程拥有独立的资源,包括内存、文件句柄等。

开销大:创建和销毁进程的开销较大,进程间通信(IPC)也相对复杂。

上下文切换:进程的上下文切换开销较大,因为需要切换内存空间和资源。

使用场景

适用于需要强隔离和独立资源的场景,如独立的服务、应用程序等。

线程 (Thread)

线程是进程内的执行单元,一个进程可以包含多个线程。线程共享进程的资源(如内存空间、文件描述符)。

线程的特点

共享资源:同一进程内的线程共享内存和资源,通信方便。

轻量级:线程的创建和销毁开销较小,上下文切换较快。

并发执行:多线程可以并发执行,提高程序的响应速度和资源利用率。

同步问题:由于共享资源,线程间需要同步机制(如锁)来避免资源竞争和数据不一致。

使用场景

适用于需要并发执行的任务,如多任务处理、并行计算等。

管程 (Monitor)

管程是一种高级的同步机制,用于管理共享资源的并发访问。它将共享资源和访问资源的代码封装在一起,通过条件变量和互斥锁来实现同步。

管程特点

封装性:将共享资源和同步代码封装在一起,提供更高层次的抽象。

互斥访问:通过互斥锁确保同一时刻只有一个线程可以访问共享资源。

条件同步:使用条件变量来协调线程间的执行顺序。

使用场景

适用于需要对共享资源进行复杂同步操作的场景,如操作系统内核、并发数据结构等。

协程 (Coroutine)

协程是一种比线程更轻量级的并发执行单元。协程由程序自身调度,而不是由操作系统内核调度。协程可以在执行过程中主动让出控制权,以便其他协程运行。

协程特点

  • 轻量级:协程的创建和切换开销极小,通常在用户态完成。
  • 主动让出:协程通过显式的调用(如yield)让出控制权,实现合作式多任务。
  • 非抢占式:协程之间的切换是合作式的,不存在抢占问题。
  • 栈独立:每个协程有自己的栈,避免了线程间共享栈带来的同步问题。
使用场景

适用于需要大量并发任务且切换频繁的场景,如高并发网络服务器、异步编程等。

用户线程与守护线程区别

用户线程

用户线程是应用程序创建的普通线程,也称为非守护线程。当所有用户线程都结束时,Java 虚拟机 (JVM) 也会退出。

特点

生命周期:用户线程的生命周期由应用程序控制。只要有一个用户线程在运行,JVM 就会继续运行。

重要性:用户线程通常用于执行应用程序的主要任务,例如处理业务逻辑、执行计算等。

关闭 JVM:JVM 只有在所有用户线程都结束后才会退出,即使还有守护线程在运行。

使用场景

适用于需要执行重要任务且不能中途被终止的线程。例如:处理用户请求的线程,执行关键业务逻辑的线程

守护线程 (Daemon Thread)

守护线程是为其他线程提供服务和支持的线程。当所有非守护线程(用户线程)都结束时,JVM 会自动退出,即使守护线程还在运行。

特点

生命周期:守护线程的生命周期依赖于用户线程。当所有用户线程结束时,守护线程也会自动终止。

后台任务:守护线程通常用于执行后台任务,如垃圾回收、日志记录等。

低优先级:守护线程通常优先级较低,因为它们主要为用户线程提供支持。

使用场景

适用于执行后台任务或辅助任务的线程,这些任务不需要在 JVM 退出时完成。例如:JVM 的垃圾回收线程,日志记录线程,监控和统计线程

Java线程的创建方式

继承Thread类
通过继承java.lang.Thread类并重写其run方法来创建线程。
实现Runnable接口
通过实现java.lang.Runnable接口并将其传递给Thread对象来创建线程。
实现Callable接口和使用FutureTask
通过实现java.util.concurrent.Callable接口来创建线程,并使用FutureTask来管理返回结果。

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

public class MyCallable implements Callable<String> {

@Override

public String call() throws Exception {

return "Callable result";

}

public static void main(String[] args) {

MyCallable myCallable = new MyCallable();

FutureTask<String> futureTask = new FutureTask<>(myCallable);

Thread thread = new Thread(futureTask);

thread.start();

try {

System.out.println("Result: " + futureTask.get());

} catch (InterruptedException | ExecutionException e) {

e.printStackTrace();

}

}

}

使用线程池
通过java.util.concurrent.ExecutorService创建和管理线程池,避免手动创建和管理线程。

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ThreadPoolExample {

public static void main(String[] args) {

ExecutorService executorService = Executors.newFixedThreadPool(3);

for (int i = 0; i < 5; i++) {

executorService.execute(() -> {

System.out.println("Thread pool task is running");

});

}

executorService.shutdown();

}

}

使用Lambda表达式 (Java 8及以上)
通过Lambda表达式简化Runnable接口的实现。

public class LambdaExample {

public static void main(String[] args) {

Thread thread = new Thread(() -> System.out.println("Lambda thread is running"));

thread.start();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值