栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程JUC

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程JUC

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 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 implements Future, CompletionStage

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/276674.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号