多线程
文章平均质量分 78
这个名字先用着
这个作者很懒,什么都没留下…
展开
-
java线程池详解
目录一、线程池的优势:二、线程池的架构图:三、Executors工具类中几个重点的创建线程池的方法:一、线程池的优势:为何要用线程池,总的来说有以下几个原因:总体来说,线程池有如下的优势:(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。(2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。二、线程池原创 2022-03-28 22:56:03 · 1121 阅读 · 0 评论 -
生产者消费者模式三种实现方式
1.什么是生产者消费者模式:生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行解耦,如工厂模式的第三者是工厂类,模板模式的第三者是模板类。在学习一些设计模式的过程中,如果先找到原创 2022-03-28 18:20:18 · 18696 阅读 · 4 评论 -
Synchronized和Lock的区别
原始构成:synchronized 是关键字属于 JVM 层面,monitorenter(底层是通过 monitor 对象来完成, 其实 wait/notify 等方法也依赖于 monitor 对象只有在同步块或方法中才能调 wait/notify 等方法)monitorexitLock 是具体类(java.util.concurrent.locks.Lock)是 api 层面的锁使用方法:synchronized 不需要用户去手动释放锁,当 synchronized 代码执..原创 2022-03-25 09:18:16 · 837 阅读 · 0 评论 -
JUC之阻塞队列
1. 什么是阻塞队列:阻塞队列(BlockingQueue)是这样的一种数据结构,它是一个队列(类似于一个List), 是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。当阻塞队列为空时,从队列中获取元素的操作将会被阻塞。当阻塞队列为满时,从队列里添加元原创 2022-03-23 23:23:21 · 2275 阅读 · 0 评论 -
JUC之自旋锁
自旋锁的提出背景:由于在多处理器环境中某些资源的有限性,有时需要互斥访问(mutual exclusion),这时候就需要引入锁的概念,只有获取了锁的线程才能够对资源进行访问,由于多线程的核心是CPU的时间分片,所以同一时刻只能有一个线程获取到锁。那么就面临一个问题,那么没有获取到锁的线程应该怎么办?通常有两种处理方式:一种是没有获取到锁的线程就一直循环等待判断该资源是否已经释放锁,这种锁叫做自旋锁,它不用将线程阻塞起来(NON-BLOCKING);还有一种处理方式就是把自己阻塞起来,等待重新调度请求,原创 2022-03-21 18:33:53 · 774 阅读 · 0 评论 -
java并发编程之CAS透彻理解
那什么是CAS呢?CAS,compare and swap,即比较并交换源码:CAS底层:原创 2022-03-19 11:43:58 · 165 阅读 · 0 评论 -
synchronized 和 volatile区别
synchronized 和 volatile 的区别是什么?synchronized 表示只有一个线程可以获取作用对象的锁,执行代码,阻塞其他线程。volatile 表示变量在 CPU 的寄存器中是不确定的,必须从主存中读取。保证多线程环境下变量的可见性;禁止指令重排序。区别volatile 是变量修饰符;synchronized 可以修饰类、方法、变量。volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。volatil原创 2022-03-19 07:46:04 · 128 阅读 · 0 评论 -
AQS介绍
AQS是什么:代码演示:原创 2022-03-17 19:36:14 · 1033 阅读 · 1 评论 -
线程的等待和唤醒机制
三种让线程等待和唤醒的方法:LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程:第一种方式:synchronized + wait + notify:即使用Object中的wait方法让线程等待,使用Object中的notify方法唤醒线程:代码演示:存在的弊端:问题一:报异常,证明 wait + notify不能脱离synchronized 代码块或者方法。问题二:被阻塞的结果,证明wait + notify顺序不能颠倒,只能先等待后唤醒。等待中的线程才能.原创 2022-03-15 15:37:24 · 6572 阅读 · 0 评论 -
sleep方法和wait方法的区别-详细
sleep()是Thread类中的方法,而wait()则是Object类中的方法。sleep不释放对象锁,wait放弃对象锁。sleep()方法导致了程序暂停,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。wait()方法会导致线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。使用范围:wait,notify和notifyA..原创 2022-03-08 17:50:33 · 5257 阅读 · 0 评论 -
线程start() 和 run()的区别
首先需要知道线程的几个状态以及多线程工作方式。new 一个Thread,线程进入了新建状态,调用start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到 时间片 后就可以开始运行了。start() 会执行线程的相应准备工作,然后自动执行run() 方法的内容,这是真正的多线程工作。而直接执行run() 方法,会把run 方法当成一个main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。总的来说:调用start 方法方可启动线程并使线程进入就绪状态,而run原创 2022-03-08 16:51:54 · 7573 阅读 · 0 评论 -
runnable 和 callable区别
runnable 和 callable 有什么区别?相同点:1、两者都是接口;(废话)2、两者都可用来编写多线程程序;3、两者都需要调用Thread.start()启动线程;不同点:1、两者最大的不同点是:Runnable 接口 run 方法无返回值;Callable 接口 call 方法有返回值。2、Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;Callable 接口 call 方法允许抛出异常,可以获取异常信息。注意:Callalbe接口支持返回执行结果,需要调原创 2022-03-08 16:27:35 · 946 阅读 · 0 评论 -
多线程和多线程的优劣
多线程概念:多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。多线程的好处:可以提高 CPU 的利用率。在多线程程序中,一个线程必须等待的时候,CPU 可以运行其它的线程而不是等待,这样就大大提高了程序的效率。也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。多线程的劣势:线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;多线程需要协调和管理,所以需要 CPU 时间跟踪线程;线程之间对共享资源的访问会相互影响,必须解决竞用共享原创 2022-03-08 12:36:43 · 161 阅读 · 0 评论 -
volatile关键字
volatile关键字的两层语义:一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:1)禁用缓存,保证内存可见性。保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,它会保证修改的值会立即被更新到主存,这新值对其他线程来说是立即可见的。2)禁止指令重排。指令重排:处理器为了提高程序运行效率,处理器根据指令之间的数据依赖性,可能会对指令进行重排序,单线程下可以保证程序最终执行结果和代码顺序执行的结果是一致的,但是多线程下有可能出原创 2022-03-08 12:16:48 · 91 阅读 · 0 评论 -
并行和并发的区别
并行和并发有什么区别?并发:一个时间段内,一个 CPU 核上 来回切换着 执行多个任务,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。并行:同一时刻,多个处理器或多核处理器 同时处理多个任务,是真正意义上的“同时进行”。串行:由一个线程按顺序执行多个任务。由于任务、方法都在一个线程执行所以不存在线程不安全情况,也就不存在临界区的问题。做一个形象的比喻:并发 = 两个队列和一台咖啡机。并行 = 两个队列和两台咖啡机。串行 = 一个队列和一台咖啡机。或者这样理解:并发相当于原创 2022-03-08 11:57:01 · 83 阅读 · 0 评论 -
并发编程三要素详解
目录并发编程三要素:并发编程三要素总结并发编程三要素详解:原子性:可见性:有序性:volatile关键字的两层语义:出现线程安全问题的原因:解决办法:并发编程三要素:并发编程三要素总结并发编程三要素(线程的安全性问题体现在):原子性:原子,即一个不可再被分割的颗粒。 原子性指的是一个或多个操作要么全部执行成功,要么全部执行失败。原子性(Atomicity):在一次或多次操作中,要么所有的操作都执行并且不会受其他因素干扰而中断,要么所有的操作都不执行可见性:一个线程对共享变量的修改,其他线程原创 2022-03-08 11:28:57 · 899 阅读 · 0 评论 -
JUC之线程池详解
使用:原创 2022-03-07 15:20:35 · 767 阅读 · 0 评论 -
JUC之读写锁/独占锁(写锁)和共享锁(读锁)
乐观锁悲观锁:写锁的死锁:原创 2022-03-06 22:03:58 · 347 阅读 · 0 评论 -
JUC之Semaphore信号灯/信号量
目录Semaphore概念:代码演示Semaphore:Semaphore实现原理:Semaphore概念:1、Semaphore 是什么:Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。可以把它简单的理解成我们停车场入口立着的那个显示屏,每有一辆车进入停车场显示屏就会显示剩余车位减1,每有一辆车从停车场出去,显示屏上显示的剩余车辆就会加1,当显示屏上的剩余车位为0时,停车场入口的栏杆就不会再打开,车辆就无法进入停车场了原创 2022-03-06 20:30:17 · 197 阅读 · 0 评论 -
JUC之常用辅助类CyclicBarrier
目录一、CyclicBarrier介绍:二、CyclicBarrier构造方法:三、维护锁状态逻辑:四、CyclicBarrier的重复使用:五、CyclicBarrier代码:一、CyclicBarrier介绍:从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。官网解释:允许一组线程全部等待彼此达到共同屏障点的同步辅助。循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。原创 2022-03-06 20:13:16 · 112 阅读 · 0 评论 -
JUC之常用辅助类CountDownLatch
CountDownLatch:1.背景:countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。存在于java.util.cucurrent包下。2.概念:countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用).原创 2022-03-06 19:25:44 · 215 阅读 · 0 评论 -
创建线程的方法之Callable接口
未来任务:原创 2022-03-05 18:22:52 · 62 阅读 · 0 评论 -
高并发编程之死锁
演示死锁:原创 2022-03-05 17:25:52 · 405 阅读 · 0 评论 -
可重入锁和不可重入锁详解
可以进行循环递归调用,因为可以重新进去调用原创 2022-03-05 12:31:10 · 7401 阅读 · 0 评论 -
公平锁和非公平锁
公平锁公平锁是指多个线程按照申请锁的顺序来获取锁,线程直接进入队列中排队,队列中的第一个线程才能获得锁。公平锁的优点是等待锁的线程不会饿死。缺点是整体吞吐效率相对非公平锁要低,等待队列中除第一个线程以外的所有线程都会阻塞,CPU 唤醒阻塞线程的开销比非公平锁大。非公平锁非公平锁是多个线程加锁时直接尝试获取锁,获取不到才会到等待队列的队尾等待。但如果此时锁刚好可用,那么这个线程可以无需阻塞直接获取到锁,所以非公平锁有可能出现后申请锁的线程先获取锁的场景。非公平锁的优点是可以减少唤起线程的开销,整体的吞吐原创 2022-03-05 12:00:15 · 7690 阅读 · 0 评论 -
sync锁得住八种情况
原创 2022-03-05 11:54:50 · 120 阅读 · 0 评论 -
JUC之线程安全的集合
当一边往集合添加数据,一边取数据的时候,会出现并发修改异常;vector:所有方法都是sync修饰的方法二:方法三:工作中常用:原创 2022-03-04 18:41:01 · 2392 阅读 · 0 评论 -
JUC之线程通信
Java多线程的wait()方法和notify()方法这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的monitor(俗称“锁”),否则会抛出IllegalMonitorStateException异常,所以这两个方法必须在同步块代码里面调用。wait():阻塞当前线程notify():唤起被wait()阻塞的线程...原创 2022-03-04 11:19:07 · 466 阅读 · 0 评论 -
JUC之Lock接口
说明:sync的上锁和解锁是自动完成的,当然我们也可以手动上锁和解锁Lock和synchronized的选择总结来说,Lock和synchronized有以下几点不同:1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在fi...原创 2022-03-04 10:19:58 · 3021 阅读 · 0 评论 -
JUC概述
JUC概述:线程和进程的概念:总结:线程的几个状态:NEW:新建RUNNABLE:准备就绪BLOCKED:阻塞WAITING:不见不散TIMED_WAITING:过时不候TERMINATED:终结两个方法:wait方法和sleep方法:1.相同点:(1)一旦执行方法,都可以使当前线程进入阻塞状态2.不同点:(1)sleep()方法是Thread类中的静态方法;而wait()方法是Object类中的方法;(2)sleep()方法可以在任何地方调用;而wait()方法只能原创 2022-03-03 21:04:34 · 380 阅读 · 0 评论 -
java线程池
目录什么是线程池?线程池7大参数和4大拒绝策略说明:Executors开启线程池的方式:线程池介绍:什么是线程池?线程池是为了提高程序执行效率,尽量减少线程对象的创建和销毁的次数而产生的一种技术。线程池内部维护了两个集合,一个是线程的集合,另一个是任务集合。线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。阿里Java开发手册中强烈要求我们不允许使用Executors原创 2021-01-25 14:59:37 · 104 阅读 · 0 评论 -
java阻塞队列
队列:常用方法:参考:https://baijiahao.baidu.com/s?id=1659873724613844132&wfr=spider&for=pchttps://blog.csdn.net/xiewenfeng520/article/details/107100303/https://www.cnblogs.com/bjxq-cs88/p/9759571.html原创 2021-01-22 05:13:48 · 184 阅读 · 0 评论 -
JUC并发编程
Lock:condition进行精准通知和唤醒:Lock中的Condition condition = lock.newCondition();condition类似于同步代码块中的同步监视器。condition能进行精准通知和唤醒。代码演示如下:package com.fan.domain.juc;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.u原创 2021-01-18 22:26:02 · 155 阅读 · 2 评论 -
java线程同步
为什么要用线程同步?问题的提出:1.多个线程执行的不确定性引起执行结果的不确定性。2. 多个线程对 同一个账户的共享,会造成操作的不完整性,会破坏数据。当多个用户在同一时刻操作同一个账户的时候,就可能会出现线程安全的问题。线程同步案例:卖票例子:创建三个窗口买票,总票数为100张,使用实现Runnable接口的方式1.问题:买票过程中,出现了重票,错票—>出现了线程安全的问题。2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。3.如何原创 2021-01-11 19:14:16 · 191 阅读 · 0 评论 -
java多线程
概述;多线程的创创建:方式一:继承Thread类1.创建一个继承Thread类的子类。2.重写Thread类的run()方法—>将此线程执行的操作声明在run()中。3.创建Thread类的子类对象。(在主线程中做)4.通过此对象调用start().代码演示:package com.fan.thread1;//1.创建一个继承于Thread类的子类 class MyThread extends Thread { //2.重写Thread类的run方法原创 2021-01-10 14:28:05 · 416 阅读 · 2 评论