(大厂必备)厂长熬夜爆肝万字之多线程高并发juc编程⭐学妹已收藏(代码片段)

java厂长 java厂长     2023-01-12     511

关键词:

🔥(大厂必备)厂长熬夜爆肝万字之多线程高并发JUC编程(一)⭐学妹已收藏

❤️‍ 大家好,我是java厂长,今天带你们体验一把多线程高并发的面试高频!❤️‍

关于作者

  • 作者介绍

🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

JUC学习

1、什么是JUC


源码+官方文档

JUC是 java util concurrent

面试高频问JUC~!

java.util 是Java的一个工具包

业务:普通的线程代码 Thread

Runnable: 没有返回值、效率相比于Callable 相对较低!

2、线程和进程

进程:一个程序,允许一个java程序会进程里面会出现一个java.exe;数据+代码+pcb

一个进程可以包含多个线程,至少包含一个线程!

Java默认有几个线程?2个线程! main线程、GC线程

线程:开了一个进程qq,聊天打字,消息提示(线程负责的)

对于Java而言:Thread、Runable、Callable进行开启线程的。

JAVA真的可以开启线程吗? 开不了的!
原因Java没有权限去开启线程、操作硬件的,这是一个native的一个本地方法,它调用的底层的C++代码。

并发、并行

并发: 多线程操作同一个资源。

  • CPU 只有一核,模拟出来多条线程,那么我们就可以使用CPU快速交替,来模拟多线程。

并行: 多个人并排行走。

  • CPU多核,多个线程可以同时执行。
public class Test 
    public static void main(String[] args) 
        //获取cpu的核数
        System.out.println(Runtime.getRuntime().availableProcessors());
    

并发编程的本质:充分利用CPU的资源!

线程的6个状态

public enum State 
    	//创建
        NEW,

    	//运行
        RUNNABLE,
    
    	//阻塞
        BLOCKED,
    
    	//等待
        WAITING,
    
    	//超时等待
        TIMED_WAITING,

    	//终止
        TERMINATED;
    

面试题:谈一谈wait和sleep区别?

区别waitsleep
操作的类ObjectThread
锁的释放会释放锁抱着锁睡觉
范围同步代码块中任何地方
异常捕获不需要捕获异常需要捕获异常

3、Lock锁(重点)

synchronized锁问题

package com.zmz.day01;
/**
 * @ProjectName: Juc
 * @Package: com.zmz.day01
 * @ClassName: TicketTest
 * @Author: 张晟睿
 * @Date: 2021/9/5 14:01
 * @Version: 1.0
 */
//资源类 属性 + 方法 oop
class Ticket
    private int num = 50;
    //卖票方式  synchronized 本质:队列 锁
    public synchronized void sale()
        if(num > 0)
            System.out.println(Thread.currentThread().getName()+ " 卖出了第"+ num +" 张票,剩余:"+ --num +" 张票");
        
    



public class TicketTest 
    public static void main(String[] args) 
        //多线陈操作
        //并发:多个线程操作同一个资源ticket
        Ticket ticket = new Ticket();
        //@FunctionalInterface 函数式接口 jdk1.8之后 lambda表达式
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"A").start();
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"B").start();
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"C").start();
    

Lock接口

公平锁: 公平,必须先来后到~;

非公平锁: 不公平,可以插队;(默认为非公平锁)

使用Lock进行操作

package com.zmz.day01;/**
 * @ProjectName: Juc
 * @Package: com.zmz.day01
 * @ClassName: TicketTest2
 * @Author: 张晟睿
 * @Date: 2021/9/5 16:15
 * @Version: 1.0
 */

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *@ClassName TicketTest2
 *@Description
 *@Author 张晟睿
 *@Date 2021/9/5
 **/

class Ticket2
    /*
    * 加锁三步
    * 1.实例化lock对象
    * 2.lock加锁
    * 3.unlock解锁
    * */
    Lock l = new ReentrantLock();
    private int num = 50;
    //卖票方式  synchronized 本质:队列 锁
    public  void sale()
        //加锁
        l.lock();
        try 
            //业务代码
            if(num > 0)
                System.out.println(Thread.currentThread().getName()+ " 卖出了第"+ num +" 张票,剩余:"+ --num +" 张票");
            
         catch (Exception e) 
            e.printStackTrace();
         finally 
            //解锁
            l.unlock();
        
    



public class TicketTest2 
    public static void main(String[] args) 
        //多线陈操作
        //并发:多个线程操作同一个资源ticket
        Ticket ticket = new Ticket();
        //@FunctionalInterface 函数式接口 jdk1.8之后 lambda表达式
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"A").start();
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"B").start();
        new Thread(()->
            for (int i = 0; i < 60; i++) 
                ticket.sale();
            
        ,"C").start();
    

区别synchronizedlock
名称属于关键字属于对象
状态不可以获取锁的状态可以获取锁的状态
锁的管理自动释放锁需要手动加锁以及释放锁
线程自己抱着锁等待
可重入锁,不可以中断的,非公平的可重入的,可以判断锁,可以自己设置公平锁和非公平锁
代码同步适合少量的代码同步适合大量的代码同步

4、生产者消费者问题

synchronized版

package com.zmz.day01;
/**
 * @ProjectName: Juc
 * @Package: com.zmz.day01
 * @ClassName: TicketTest3
 * @Author: 张晟睿
 * @Date: 2021/9/5 16:35
 * @Version: 1.0
 */

/**
 *@ClassName TicketTest3
 *@Description
 *@Author 张晟睿
 *@Date 2021/9/5
 **/
public class TicketTest3 
    public static void main(String[] args) 
        Data data = new Data();
        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.increment();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"A").start();

        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.decrement();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"B").start();
    



//判断等待  业务  唤醒
class Data
    private int number = 0;
    //      +1操作
    public synchronized void increment() throws InterruptedException 
        if(number != 0 )
            this.wait();
        
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    
    //      -1操作
    public synchronized void decrement() throws InterruptedException
        if (number == 0)
            this.wait();
        
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    

问题存在,A线程B线程,现在如果我有四个线程A B C D!该怎么去解决问题

if判断改为While判断就可以解决虚假唤醒的问题。

package com.zmz.day01;
/**
 * @ProjectName: Juc
 * @Package: com.zmz.day01
 * @ClassName: TicketTest3
 * @Author: 张晟睿
 * @Date: 2021/9/5 16:35
 * @Version: 1.0
 */

/**
 *@ClassName TicketTest3
 *@Description
 *@Author 张晟睿
 *@Date 2021/9/5
 **/
//线程之间的通讯问题:生产者和消费者的问题!  等待唤醒,通知唤醒
//线程交替执行 A   B操作同一个资源
public class TicketTest3 
    public static void main(String[] args) 
        Data data = new Data();
        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.increment();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"A").start();

        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.decrement();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"B").start();
        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.decrement();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"C").start();
        new Thread(()->
            for (int i = 0; i < 10; i++) 
                try 
                    data.decrement();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        ,"D").start();
    



//判断等待  业务  唤醒
class Data
    private int number = 0;
    //      +1操作
    public synchronized void increment() throws InterruptedException 
        while(number != 0 )
            this.wait();
        
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    
    //      -1操作
    public synchronized void decrement() throws InterruptedException
        while (number == 0)
            this.wait();
        
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    

JUC版本的解决A B C D多线程的问题

package com.zmz.day01;
/**
 * @ProjectName: Juc
 * @Package: com.zmz.day01
 * @ClassName: JucTest1
 * @Author: 张晟睿
 * @Date: 2021/9/5 19:34
 * @Version: 1.0
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *@ClassName JucTest1
 *@Description
 *@Author 张晟睿
 *@Date 2021/9/5
 **/
public class JucTest1 
    public static void main(String[] args) 
        Data2 data = new Data2();

        new Thread(()->for(int i=0;i<10;i++) 
            data.increment();
        
        ,"A").start();
        new Thread(()->for(int i=0;i<10;i++) 
            data.decrement();
        ,"B").start();
        new Thread(()->for(int i=0;i<10;i++) 
            data.increment();
        
        ,"C").start();
        new Thread(()->for(int i=0;i<10;i++) 
            data.decrement();
        
        ,"D").start();
    



class Data2
    private int number = 0;
    //lock锁
    Lock l = new ReentrantLock()熬夜爆肝万字c#基础入门大总结建议收藏(代码片段)

往期文章分享点击跳转=>熬夜再战Android从青铜到王者-UI组件快速搭建App界面点击跳转=>熬夜再战Android从青铜到王者-几个适配方案点击跳转=>熬夜再战Android从青铜到王者-开发效率插件篇点击跳转=>Unity粒子特... 查看详情

熬夜爆肝万字c#基础入门大总结建议收藏(代码片段)

...List/立体画廊等,玩出花儿来点击跳转=>Unity新手必备5款宝藏插件–价值上千元白嫖最新版👉关于作者众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多... 查看详情

建议收藏|熬夜爆肝万字文带你了解dom,文末有彩蛋嗷!!!!✨✨✨(代码片段)

感激相遇你好我是阿ken作者:请叫我阿ken链接:请叫我阿ken主页链接来源:CSDN著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。🌊🌈关于前言:文章部分内容及图片出自网... 查看详情

建议收藏|熬夜爆肝万字文带你了解dom,文末有彩蛋嗷!!!!✨✨✨(代码片段)

感激相遇你好我是阿ken作者:请叫我阿ken链接:请叫我阿ken主页链接来源:CSDN著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。🌊🌈关于前言:文章部分内容及图片出自网... 查看详情

中秋节爆肝万字,带你熟悉linux进程的基本操作!!!(代码片段)

今天是中秋节,祝各位小伙伴中秋节快乐,记得吃月饼吖图片来自网络,侵联删Linux进程基本操作1.进程基本概念在Linux中进程信息被保存在task_struct(PCB)2.查看进程的方法pspsaux|greapmyprocls/proc3.创建进程fork():创建一个子进程#i... 查看详情

中秋节爆肝万字,带你熟悉linux进程的基本操作!!!(代码片段)

今天是中秋节,祝各位小伙伴中秋节快乐,记得吃月饼吖图片来自网络,侵联删Linux进程基本操作1.进程基本概念在Linux中进程信息被保存在task_struct(PCB)2.查看进程的方法pspsaux|greapmyprocls/proc3.创建进程fork():创建一个子进程#i... 查看详情

❤️爆肝万字!一文最全总结之spring从入门到入土❤️(建议收藏)(代码片段)

文章目录最新更新前言1.Spring概述1.1介绍2.IoC入门2.1什么是IoC2.2IoC入门案例1(基础案例)2.3IoC入门案例2(依赖注入)2.4IoC入门案例3(面向接口编程)2.5IoC入门案例4(整合JUnit4)3.IoC详解3.1Bean的创建... 查看详情

❤️爆肝万字!一文最全总结之spring从入门到入土❤️(建议收藏)(代码片段)

文章目录前言1.Spring概述1.1介绍2.IoC入门2.1什么是IoC2.2IoC入门案例1(基础案例)2.3IoC入门案例2(依赖注入)2.4IoC入门案例3(面向接口编程)2.5IoC入门案例4(整合JUnit4)3.IoC详解3.1Bean的创建3.2依赖注... 查看详情

❤️爆肝万字整理的综合架构web服务之nginx详解❤️,附建议收藏(代码片段)

文章目录nginx服务配置详细介绍关于作者前言一、nginxweb入门简介1.1什么是nginx1.2常见的网站服务1.3nginx网站服务特点1.4网站页面访问原理二、nginx服务部署安装2.1实验环境2.2YUM安装2.3源码编译安装2.4nginx重要文件目录结构2.5虚拟主... 查看详情

万字讲解如何设计百万人抽奖系统?——高并发面试模板,已拿美团offer❤️建议收藏(代码片段)

❤️一条独家专栏⭐️搞技术,进大厂,聊人生📚《大厂面试突击》——面试10多家中大厂的万字总结📚《技术专家修炼》——高薪必备,企业真实场景📚《leetcode300题》——每天一道算法题,进大厂... 查看详情

pythonopencv实战画图——这次一定能行!爆肝万字,建议点赞收藏~❤️❤️❤️(代码片段)

📢📢📢📣📣📣🌻🌻🌻Hello,大家好我叫是Dream呀,一个有趣的Python博主,小白一枚,多多关照😜😜😜🏅🏅 查看详情

☀️~算法系列之爆肝万字总结七种查找算法,持续补充更新中,建议收藏~☀️(代码片段)

🍅作者主页:Roninaxious🍅欢迎点赞👍收藏⭐留言📝🍅话不多说🍁开卷!🚢顺序查找算法🚢二分查找算法💥优化二分查找算法🚢插值查找算法🚢斐波那契查找算法🚢顺序... 查看详情

熬夜爆肝!c++核心进阶知识点汇总整理万字干货预警建议收藏(代码片段)

...C++基础入门知识点,没看过的可以看看喔!熬夜爆肝!C++基础入门大合集【万字干货预警建议收藏】今天继续整 查看详情

❤️大学三年沉淀,把我的学习经验分享给你,爆肝万字带你走进编程世界!❤️(代码片段)

Hello,大家好,我是Alex。时光匆匆,暑假过的很快,转眼又到了大学的开学季,我也是又混进了我们学院的新生群,发现大家对计算机充满着迷之向往,啊哈哈哈,不过没有人带着入门还是很容易... 查看详情

网易一面:如何设计线程池?请手写一个简单线程池?(代码片段)

...a面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪酬猛涨!加尼恩免费领免费赠送经典图书:《Java高并发核心编程(卷1... 查看详情

❤爆肝万字手把手教你springboot+mybatis+jquery+html5从0开始写网页一学就会!(内附源码)❤(代码片段)

今天带给大家的是SpringBoot+MyBatis+jQuery+HTML5+CSS简单实现前后端交互,保证干货满满,看完你就可以动手写你自己的程序!首先得需要你创建一个SpringBoot项目,具体怎么创建这里久不多说啦。其次,... 查看详情

juc高并发编程(代码片段)

文章目录1.什么是JUC1.1.JUC简介1.2.进程与线程1.3.线程的状态1.3.1线程状态枚举类1.3.2.wait/sleep的区别1.4.并发与并行1.4.1.串行模式1.4.2.并行模式1.4.3.并发1.4.4.小结(重点)1.5.管程1.6.用户线程和守护线程2.Lock接口2.1.Synchronized2.1.1.Synchroniz... 查看详情

juc高并发编程(代码片段)

文章目录1.什么是JUC1.1.JUC简介1.2.进程与线程1.3.线程的状态1.3.1线程状态枚举类1.3.2.wait/sleep的区别1.4.并发与并行1.4.1.串行模式1.4.2.并行模式1.4.3.并发1.4.4.小结(重点)1.5.管程1.6.用户线程和守护线程2.Lock接口2.1.Synchronized2.1.1.Synchroniz... 查看详情