![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
多线程
文章平均质量分 73
多线程
光哥_帅
技术就是知识,改变命运!!!
展开
-
【多线程】生产者消费者传统版和阻塞队列版
前言等待与唤醒机制其实就是经典的生产者与消费者问题我们知道,生产者要想和消费者作用在一件产品上,必须要用到锁机制。通过锁机制保证一个产品同一时间只有一个角色在执行。下面将分别使用Synchronized和Lock锁解决生产者和消费者的问题。1Synchronized版/** * 线程之间的通信问题:生产者与消费者问题! * A和B操作同一个变量,线程交替执行,num=0 * A num+1 * B num-1 */public class A { public static v转载 2021-03-07 23:01:42 · 240 阅读 · 2 评论 -
【多线程】虚假唤醒(什么时候用while,什么时候用if)
那什么是假唤醒?当一个条件满足时,很多线程都被唤醒了,但是只有其中部分是有用的唤醒,其它的唤醒都是无用功比如说买货,如果商品本来没有货物,突然进了一件商品,这是所有的线程都被唤醒了但是只能一个人买,所以其他人都是假唤醒,获取不到对象的锁避免虚假唤醒下面是避免虚假唤醒的示例:package duoxiancheng.bao;/* * 虚假唤醒的解决: * wait要始终保证在while循环当中。 */public class LockTest { public stati转载 2021-03-07 12:28:00 · 1479 阅读 · 1 评论 -
【多线程】LockSupport的线程等待唤醒机制
前言:传统的线程等待唤醒机制有两种方式分别是synchronized(wait和notify)和JUC包中的显示锁Lock(condition的await()方法和signal()方法),但是这两个方式有两个缺点,分别是都不能脱离synchronized,和lock、unlock,如果脱离就会报错,还有就是wait和notify,await和signal的执行顺序要固定,必须先wait然后在notify,否则会导致程序无法结束。所以出现第三种方式,那就是LockSupport(park和unpark),原创 2021-02-06 23:41:18 · 396 阅读 · 1 评论 -
【多线程】锁消除和锁粗化
锁粗化通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽可能短,但是大某些情况下,一个程序对同一个锁不间断、高频地请求、同步与释放,会消耗掉一定的系统资源,因为锁的讲求、同步与释放本身会带来性能损耗,这样高频的锁请求就反而不利于系统性能的优化了,虽然单次同步操作的时间可能很短。锁粗化就是告诉我们任何事情都有个度,有些情况下我们反而希望把很多次锁的请求合并成一个请求,以降低短时间内大量锁请求、同步、释放带来的性能损耗。一种极端的情况如下:public void doSomethingM转载 2021-01-31 22:10:31 · 838 阅读 · 0 评论 -
【多线程】 LongAdder的原理
前言:我们都比较熟悉AtomicInteger、AtomicLong,在并发量不多的情况下,他们可以使用非阻塞的CAS算法原子性地更新某一个变量。但是在并发量大的情况下,它的自旋的概率增大,会浪费cpu的资源。而LongAdder是JDK1.8新增的原子操作类,它解决了AtomicInteger、AtomicLong的问题,至于怎么解决的,接下来看下面的解释。1、LongAdderLongAdder可以是计数器的增强版,高并发下性能会更好,适合频繁的更新,但是不太频繁读取,汇总统计信息时使用分成多个操原创 2021-01-30 23:03:01 · 738 阅读 · 0 评论 -
【多线程 十】线程池的应用以及其原理剖析
1、线程池概念(1)线程池管理器用于创建并管理线程池,包括创建线程池、销毁线程池、添加新任务;(2)工作线程线程池中线程,在没有任务时处于等待状态,可以循环的执行任务(3)任务接口每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后的收尾工作,任务的执行状态等(4)任务队列用于存放没有处理的任务,提供一种缓冲机制。2、线程池API(1)接口定义和实现类类型名称描述接口Excutor定义了 执行任务的方法execute接原创 2021-01-16 23:42:52 · 314 阅读 · 2 评论 -
【java 设计模式】 单例模式精解(面试再也不用怕了)
前言这篇 博客是跑更问底的学习单例模式,看了本博客,对于一般的面试官,你都可以手撕了,但是大神级别的面试官,后边还会补充。一、手写单例模式1、饿汉式public class Singleton { // 构造方法私有化,其他类就不能通过new的方式来创造对象 private Singleton(){ } // 内部提供一个当前的实例,必须要静态化,因为下面的静态方法要调用 private static Singleton singleton=new Singl原创 2020-06-30 20:16:53 · 319 阅读 · 3 评论 -
【多线程 九】ReentrantLock的使用
1 ReentrantLock重入锁和关键字synchronization相比,重入锁有着显示的操作过程。需要手动指定何时加锁,何时释放锁。重入锁对逻辑控制的灵活性要远远优于关键字synchronization。在退出时,必须记得释放锁,否则其他线程就没有机会访问。重入锁之所以叫重入锁,是因为这种锁能反复进入。但是只限于一个线程。//锁定几个就要释放几个try{ lock.lock(); lock.lock()}finally{ lock.unlock(); lock.un转载 2021-01-11 23:08:23 · 908 阅读 · 2 评论 -
【多线程 八】理解线程变量ThreadLocal和InheritableThreadLocal
前言:对于多线程来说,我记住最多的一句就是线程操作资源类,在资源类中变量的值的共享可以使用public static变量的形式,所有的线程都使用同一个public static 变量。线程都可以对此变量进行操作更改。但是如果想实现每一个线程都有自己的共享的变量该如何解决,于是ThreadLocal出现,解决了此问题。1 理解ThreadLocal类ThreadLocal主要解决的就是每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储 每个线程的私有数据2 代原创 2021-01-06 23:14:01 · 282 阅读 · 1 评论 -
【多线程 七】 线程间通信之join()
前言前面我们全面介绍了多线程间是如何通信的: 地址链接,接下来我们详细的介绍join方法,它有什么作用解决了什么问题。1、引入在多线程的环境中,如果要想实现这样一个效果:子线程的执行过程中比较耗费时间,但是我想 主线程在子线程执行完之后再执行,这时候有一个方法它可以解决此问题,那就是join方法2、代码展示2.1 创建一个线程MyThreadpublic class MyThread extends Thread { @Override public void run() {原创 2021-01-06 23:13:47 · 279 阅读 · 1 评论 -
【多线程 二】线程创建和启动的四种方式(以及详解Thread和Runnable方式的优缺点)
1、继承Thread其实也是实现了runnable接口的。public class Threadextend extends Thread{ @Override public void run() { for(int i=0;i<=100;i++){ System.out.print("A"+i+ "\t"); } }}public class Main { public static void main原创 2020-06-16 22:44:49 · 974 阅读 · 1 评论 -
【多线程 六】彻彻底底搞懂CAS,解决ABA问题
前言:如果不知道JMM(java 内存模型),还请看博主的上一篇博客: volatile关键字与内存可见性详解 ,因为本博客还需要JMM的理论基础。博客内容导图1、CAS是什么CAS(Compare-And-Swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问. CAS 是一种无锁的非阻塞算法的实现。以上是一本书给出的定义。其实我们在上篇博客已经提过CAS了,AtomicInteger 实现num++,AtomicInteger的底层就是原创 2020-06-23 01:11:45 · 3601 阅读 · 1 评论 -
【多线程 五】volatile关键字与内存可见性详解
前言:本篇博客内容较多,1、为什么会有volatile关键字?之前的内容我们都是用synchronize关键字进行同步,但是synchronize的效率低,每次都要cpu判断有没有锁,有锁就会阻塞。所以说synchronize是一个重量级的锁,比较耗费资源,因此引出vllatile,volatile相对synchronize 是一个轻量级的锁。2、volatile特点(1)保证内存可见性只要有一个线程将变量的值改了,那么其他的线程马上就可以得到这个改过后的值。(2)不保证原子性原子性:我们把原创 2020-06-21 17:11:07 · 1764 阅读 · 3 评论 -
【多线程 四】线程间的通信
1、为什么要处理线程间通信 :当我们需要多个线程共同协作完成一件任务,并且希望他们有规律的执行,那么此时就需要线程之间进行通信。为了能达到此种目的我们需要引入一个机制——等待唤醒机制。2、 等待唤醒机制这是多个线程间的一种协作机制。就是在一个线程进行了规定操作后 ,就进入等待状态 (wait() ), 等待其他线程执行完他们的指定代码过后 再将 其唤醒 (notify() );在有多个线程进行等待时, 如果需要 ,可以使用 notifyAll()来唤醒所有的等待线程。2.1 wait() 与not原创 2020-06-19 23:16:02 · 247 阅读 · 0 评论 -
【多线程 三】线程同步的几种方式详解
1、问题引入当多个线程共同访问共享资源的时候,就会发生线程安全的问题,比如如下的程序:三个窗口同时卖一百张票,但最后出现没有存在的票(0 -1票)代码:public class TicketRunnableImpl implements Runnable{ private int ticket=100; @Override public void run() { while(true){ if(ticket>0)原创 2020-06-18 21:35:51 · 1582 阅读 · 0 评论 -
【多线程 一】概述
前言:此篇博客对多线程是一个整体的概述过程,后续会有具体的讲解。1、导图:2、何为线程线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。java就是一个多线程的,因为一个java应用程序最少也会有三个线程,比如man()线程,gc垃圾回收程序,异常处理线程3、为什么要用多线程问题引入:举个栗子,如果单核cpu,只使用单个线程先后完成多个任务(调用多个方法),肯定比用多个线程来完成的时间更短(大家想想原创 2020-06-17 09:22:39 · 212 阅读 · 3 评论