线程JUC

本文详细介绍了Java中的并发工具包JUC,包括线程状态、synchronized和Lock的区别与用法,以及线程通信的实现。讨论了线程池的概念,展示了不同类型的线程池创建方式,并提出了线程池的使用注意事项和拒绝策略。此外,还提到了Fork/Join框架和异步编程模型CompletableFuture的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JUC

java.util.comcurrent:线程处理工具包

进程:计算机的程序关于某数据集合的一次运行活动。是系统进行资源分配和调度的基本单位,是操作系统结构的基础

线程:是操作系统能够进行运算调度的最小单位,是进程的实际运作单位

线程状态

Thread.State

public enum State{
	NEW,(新建)
	RUNNABLE,(准备就绪)
	BLOCKED,(阻塞)
	WAITING,(不见不散)
	TIMED_WAITING,(过时不候)
	TERMINATED(终结)
}

wait()和sleep()区别:

(1)sleep()是Thread的静态方法,wait()是Object的方法,任何对象实例都能调用

(2)sleep()不会释放锁,wait()会释放锁,前提是代码要在synchronized中

并发与并行区别

并发:同一时刻多个线程访问同一资源,多个线程对一个点

并行:多项工作一起执行,最后再汇总

synchronized同步锁

synchronized是java关键字,是内置特性,系统会自动让线程释放对锁的占用

(1)同步代码块:修饰一个代码块,作用的对象是调用这个代码块的对象

(2)同步方法:修饰一个方法,作用的范围是整个方法,作用的对象是调用这个方法的对象

(3)同步静态方法:修饰一个静态方法,作用的范围是整个静态方法,作用的对象是这个类的所有对象

(4)同步类:修饰一个类,作用的范围是整个类,作用的对象是这个类的所有对象

在这里插入图片描述

Lock接口

必须主动释放锁,一般采用try…catch…finally块结构。

在这里插入图片描述

线程通信

synchronized实现

在synchronized中通过wait()和notify()来实现等待/通知模式

在这里插入图片描述

在这里插入图片描述

Lock实现

通过Lock锁的 newCondition()方法返回的Condition类对象实现等待/通知模式

await():会使当前线程等待,同时会释放锁,当其他线程调用signal()方法时,线程会重新获得锁并继续执行

signal():用于唤醒一个等待的线程

在这里插入图片描述

在这里插入图片描述

Lock定制化通信

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

集合线程安全

List

ArrayList线程不安全

在这里插入图片描述

针对ArrayList线程不安全解决方式:

(1)Vector

在这里插入图片描述

(2)使用Collections类的synchronizedList(List list)对原list进行转换

在这里插入图片描述

(3)使用CopyOnWriteArrayList初始化list

在这里插入图片描述

Set

在这里插入图片描述

Map

在这里插入图片描述

锁类型介绍

死锁

在这里插入图片描述

在这里插入图片描述

查看程序是否存在死锁

(1)先使用jps查看进程号

(2)使用jstack 进程号来查看

在这里插入图片描述

公平锁

在这里插入图片描述

悲观锁

在这里插入图片描述

悲观锁不支持并发操作,效率低 乐观锁支持并发操作,操作完成后会修改版本号,另一线程提交时会判断版本号是否一致(不一致则提交失败)

可重入锁
Lock

在这里插入图片描述

synchronized

在这里插入图片描述

Callable接口

在这里插入图片描述

在这里插入图片描述

辅助类

CountDownLatch:减少计数

在这里插入图片描述

CyclicBarrier:循环栅栏

在这里插入图片描述

Semaphore:信号灯

在这里插入图片描述

读写锁

读锁(共享锁):ReentrantReadWriteLock.readLock()

写锁(排他锁或独占锁):ReentrantReadWriteLock.writeLock()

在这里插入图片描述

在这里插入图片描述

锁降级

在这里插入图片描述

产生死锁原因

在这里插入图片描述

阻塞队列

当队列是空的,从队列中获取元素的操作会被阻塞

当队列是满的,从队列中添加元素的操作会被阻塞

在这里插入图片描述

队列中没有数据的情况下,消费者端所有线程都会被自动阻塞(挂起),直到有数据放入队列

队列中填满数据的情况下,生产者端所有线程都会被自动阻塞(挂起),直到队列中有空的位置,线程被自动唤醒

核心方法:

在这里插入图片描述
在这里插入图片描述

常见BlockingQueue:

(1)ArrayBlockingQueue:基于数组的阻塞队列实现,内部维护了一个定长数组,以便缓存队列中的数据对象

(2)LinkedBlockingQueue:基于链表的阻塞队列,内部维护着一个数据缓冲队列(由链表构成)

线程池

线程池维护着多个线程,等待着管理者分配可并发执行的任务,避免了处理短时间任务时创建和销毁线程的代价。不仅能保证内核的充分使用,还能防止过分调度

Java线程池是通过Executor框架实现

在这里插入图片描述

线程池创建
Executors方式(学习用)

(1)一池N线程:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程

// 获取指定数量的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);

(2)一池一线程:创建一个使用单个worker线程的Executor,以无界队列方式来运行该线程

// 获取单个线程池
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

(3)可扩容线程池:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空线程,若无可回收则新建线程

// 获取可扩容的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

在这里插入图片描述

自定义方式(生产用)

Executors方式创建线程池,底层源码都是new ThreadPoolExecutor()对象

ThreadPoolExecutor构造参数:

public ThreadPoolExecutor(
	int corePoolSize,//常驻线程数量
	int maximumPoolSize,//最大线程数量
	long keepAliveTime,//线程存活时间
	TimeUnit unit,//线程存活时间单位
	BlockingQueue<Runnable> workQueue,//阻塞队列
	ThreadFactory threadFactory,//线程工厂
	RejectedExecutionHandler handler//拒绝策略
)

在这里插入图片描述

线程池注意事项

(1)在创建线程池后,池中线程数为零,知直到执行execute()方法线程才创建

(2)当提交任务数 > 阻塞队列容量 + 最大线程数量时,就会触发线程池的拒绝策略

线程池拒绝策略

(1)AbortPolicy(默认):直接抛出RefectedExecutionExecption异常阻止系统正常运行

(2)CallerRunPolicy:”调用者运行“,一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量

(3)DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务

(4)DiscardPolicy:该策略摸摸丢弃无法处理的任务,不予任何处理也不排抛出异常

线程池工作原理

在这里插入图片描述

Fork/Join

将一个大任务拆分成多个子任务并行处理,最后将子任务结果合并成最后的计算结果

Fork: 将复杂任务进行分拆,大事化小

Join:把分拆任务的结果进行合并

涉及类:

(1)分支合并池:ForkJoinPool

(2)递归任务:抽象类ForkJoinTask(子类RecursiveTask)
在这里插入图片描述
在这里插入图片描述

异步编程(CompletableFuture)

public class CompletableFuture<T> implements Future<T>, CompletionStage<T>

Future接口兼容现有线程池框架

CompletionStage接口是异步编程的接口抽象

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值