多线程
文章平均质量分 81
一江溪水
这个作者很懒,什么都没留下…
展开
-
什么是自旋锁
前言阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。自旋锁在有些场景中,同步资源的锁定时间很短,为了这一小段时间去切换线程,线程挂起和恢复现场的花费可能会让系统得不偿失。如果机器有多个CPU核心,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。为了让当前线程“稍等一下”,我们需让当前线程进行自原创 2022-01-02 21:28:58 · 11308 阅读 · 0 评论 -
悲观锁 VS 乐观锁
前言Java中有很多锁,每种锁因其特性的不同,在适当的场景下的效率也有很大的差别。今天我们对比一下乐观锁和悲观锁,看看他们有什么不同和相同。乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有比较广泛的应用。悲观锁对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。悲观锁调用方式分别是 synchr原创 2021-12-26 15:01:18 · 356 阅读 · 0 评论 -
JDK的锁升级过程
原创 2021-12-25 22:56:05 · 377 阅读 · 0 评论 -
生产者-消费者模型
什么是生产者消费者模型生产者 - 消费者模型( Producer-consumer problem) 是一个非常经典的多线程并发协作的模型,在分布式系统里非常常见。这个模型由两类线程和一个缓冲区组成来组成生产者线程:生产数据,并把数据放在这个队列里面缓冲区:存放生产者的数据的地方消费者线程:从队列里面取数据,消费数据运行流程生产者和消费者在同一时间段内共用同一个存储空间生产者往存储空间中添加产品消费者从存储空间中取走产品当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。原创 2021-11-20 16:43:07 · 7001 阅读 · 0 评论 -
Java的IO流
基本概念同步和异步同步和异步是通信机制同步:同步IO是用户线程发起IO请求后需要等待或轮询内核IO操作完成后才能继续执行。异步:异步IO是用户线程发起IO请求后可以继续执行,当内核IO操作完成后会通知用户线程,或调用用户线程注册的回调函数。阻塞和非阻塞阻塞和非阻塞是调用状态阻塞:阻塞IO是IO操作需要彻底完成后才能返回用户空间。非阻塞:非阻塞IO是IO操作调用后立即返回一个状态值,无需等IO操作彻底完成。BIOBIO是同步阻塞式IO,是JDK1.4 之前的IO模型。服务器实现原创 2021-10-03 16:47:59 · 123 阅读 · 0 评论 -
AQS原理
概念AQS是AbstarctQueuedSynchronizer 的简称 ,是一个用于构建锁和同步容器的框架。juc并发 包内许多类都是基于 AQS 构建的ReentrantLockReentrantReadWriteLockFutureTaskAQS 解决了在实现同步容器时大量的细节问题。AQS 使用一个 FIFO 队列表示排队等待锁的线程,队列头结点称作 “哨兵节点” ,它不与任何线程关联。其他的节点与等待线程关联,每个阶段维护一个等待状态 waitStatus。功能独占原创 2021-09-22 17:20:46 · 1144 阅读 · 0 评论 -
比较交换CAS
概念CAS 是比较交换 CompareAndSwap 的简称,是一种用于在多线程环境下实现同步功能的机制。顾名思义就是比较并交换。简单来说,从某一内存上取值 V,和预期值 A 进行比较如果内存值 V 和预期值 A 的结果相等,那么我们就把新值 B 更新到内存;如果不相等,说明在这个过程中这个值被别的线程修改果,那么就重复上述操作直到成功为止。为什么要CASsynchronized在多线程中为了保持数据的准确性,避免多个线程同时操作某个变量,可以使用synchronized 实现同步锁。原创 2021-09-21 17:13:58 · 500 阅读 · 0 评论 -
JDK的锁优化策略
锁的优化策略JDK6对synchronized做了很多优化,引入了自适应自旋、锁消除、锁粗化、偏向锁和轻量级锁等优化策略,提高锁的效率;锁一共有4个状态,级别从低到高依次是:无锁、偏向锁、轻量级锁和重量级锁,状态会随竞争情况升级。锁可以升级但不能降级,这种只能升级不能降级的锁策略是为了提高锁获得和释放的效率。自旋锁线程同步对性能最大的影响是阻塞,挂起和恢复线程的操作都需要从用户态转入内核态完成。许多应用上共享数据的锁定只会持续很短的时间,为了这段时间去挂起和恢复线程并不值得。如果机器有多原创 2021-09-19 22:36:31 · 281 阅读 · 0 评论 -
volatile 关键字
volatile 关键字volatile 关键字解决内存可见性问题,是一种弱形式的同步。该关键字可以确保当一个线程更新共享变量时,更新操作对其他线程马上可见。当一个变量被声明为 volatile 时,线程在写入变量时不会把值缓存在寄存器或者其他地方,而是会把值刷新回主内存。当其他线程读取该共享变量时,会从主内存重新获取最新值,而不是使用当前线程的工作内存中的值。原理Java 语言提供了一种弱同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为 vol原创 2021-09-19 16:33:46 · 94 阅读 · 0 评论 -
synchronized 关键字
概念synchronized 同步块是 Java 提供的一种原子性内置锁,Java 中的每个对象都可以把它当作一个同步锁来使用,这些 Java 内置的使用者看不到的锁被称为内部锁,也叫作监视器锁。内置锁也叫排它锁,也就是当一个线程获取这个锁后,其他线程必须等待该线程释放锁后才能获取该锁。代码在进入 synchronized 代码块前会自动获取内部锁,这时候其他线程访问该同步代码块时会被阻塞挂起。拿到内部锁的线程会在正常退出同步代码块或者抛出异常后或者在同步块内调用了该内置锁资源的 wa原创 2021-09-17 15:32:03 · 61 阅读 · 0 评论 -
ThreadLocal的使用
概述ThreadLocal 为解决多线程程序的并发问题提供了一种新的思路,使用这个工具类可以很简洁地编写出优美的多线程程序。ThreadLocal 很容易让人望文生义,想当然地认为是一个 “本地线程”。其实,ThreadLocal 并不是一个 Thread,而是 Thread 的局部变量,也许把它命名为 ThreadLocalVariable 更容易让人理解一些。当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独原创 2021-09-15 16:33:38 · 7300 阅读 · 0 评论 -
扩展线程池捕获线程异常
如何捕获线程池中的线程异常简单案例我们先看一个案例,实现Runnable接口,计算两个数的商创建一个线程池,参数如下提交任务到线程池,查看执行结果执行结果我们发现,我们代码中,提交了5个线程,但最终只打印了4个结果,而且没有报何错误,很明显100/0的那个任务没有打印100/0会报除零异常,但是显然这次没有报任何错误改用execute()提交线程为了获得线程报错信息,我们可以改用execute()提交线程从这里的控制台,我们得到了部分的报错信息,但是我们只能知道异常是在原创 2021-09-15 15:37:54 · 240 阅读 · 0 评论 -
线程复用-线程池
线程池是什么池化技术能够减少资源对象的创建次数,提高程序的响应性能,特别是在高并发下这种提高更加明显线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务为什么要用线程池主要是为了减少每次获取资源的消耗,提高对资源的利用率。线程池提供了一种限制和管理资源(包括执行一个任务)。每个线程池还维护一些基本统计信息,例如已完成任务的数量。降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时,任务可以不需要的等到线程原创 2021-07-18 10:21:19 · 127 阅读 · 1 评论 -
线程与进程
进程是指计算机中已运行的程序,它是一个动态执行的过程。假设我们电脑上同时运行了浏览器、QQ 以及代码编辑器三个软件,这三个软件之所以同时运行,就是进程所起的作用。线程是操作系统能够进行运算调度的最小单位。大部分情况下,它被包含在进程之中,是进程中的实际运作单位。也就是说一个进程可以包含多个线程, 因此线程也被称为轻量级进程。线程的状态线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new) 新建状态,尚未启动的线程处于此状态;就绪(runnabl原创 2021-07-17 18:33:22 · 114 阅读 · 1 评论