JUC——多线程补充

news2024/9/27 9:21:19

前置可看

Java——多线程和锁_java多线程锁_北岭山脚鼠鼠的博客-CSDN博客

线程创建的三种方式

Thread、Runnable、Callable

Thread类 

Runable接口

Callable接口

Lamda表达式

Lamda表达式_北岭山脚鼠鼠的博客-CSDN博客

静态代理模式(Thread类的原理)

 如下代码中

  • 真实对象和代理对象都实现了同一个接口
  • 代理对象代理真实角色

好处:

        代理对象可以做很多真实对象做不了的事情

        真实对象专注做自己的事即可 

其中多线程Thread类的底部实现原理就是静态代理模式,不过被代理的实际线程对象是由Thread来创建的。

//静态代理模式
public class StaticProxy {
    public static void main(String[] args) {
        you you=new you();

        //普通调用
        WeddingCompany weddingCompany=new WeddingCompany(you);
        weddingCompany.HappyMarry();

        //lambda表达式调用
        new WeddingCompany(you).HappyMarry();

        //多线程
        new Thread(()-> System.out.println("测试")).start();
    }
}

interface Marry{

    void HappyMarry();
}

//真实角色
class you implements Marry{

    @Override
    public void HappyMarry() {
        System.out.println("鼠鼠结婚了");
    }
}

//代理角色,帮助你结婚
class WeddingCompany implements Marry{

    //代理的对象-->真实角色
    private Marry target;

    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    public void HappyMarry() {
        before();
        this.target.HappyMarry();
        after();
    }


    private void before() {
        System.out.println("结婚之前,布置现场");
    }

    private void after() {
        System.out.println("结婚之后,收尾款");
    }
}

在Java中,`Thread`类底层使用了静态代理模式来实现线程的创建和管理。静态代理模式是一种结构型设计模式,它允许你通过代理对象来控制对真实对象的访问。在`Thread`类中,`Thread`对象作为代理,用于管理真正执行线程任务的工作线程(实际的线程实例)。

具体来说,`Thread`类的静态代理模式的工作方式如下:

  • 1. **`Thread`类充当代理:** `Thread`类是代理类,它负责处理线程的生命周期、状态变化等。它提供了方法来启动、暂停、恢复、停止线程等操作。
  • 2. **实际线程对象:** 在`Thread`类中,真正执行线程任务的是一个实际的线程对象,这个线程对象通常是继承自`java.lang.Thread`的子类。这个实际的线程对象是被代理的真实对象。
  • 3. **调用`start`方法:** 当你调用`Thread`类的`start`方法时,`Thread`对象首先会执行一些必要的准备工作(例如,状态设置等),然后创建一个实际的线程对象,并调用实际线程对象的`run`方法。
  • 4. **执行线程任务:** 实际的线程对象执行线程任务。这个任务通常是在子类中的`run`方法中实现的,这是你自己定义的任务逻辑。
  • 5. **线程状态管理:** `Thread`类会在合适的时机管理线程的状态变化,例如,当线程启动时,`Thread`对象会将线程状态设置为"RUNNABLE",当线程执行完毕时,`Thread`对象会将线程状态设置为"TERMINATED"。

总之,`Thread`类在底层使用静态代理模式,通过代理对象管理实际线程对象的创建、启动、暂停、停止等操作,以实现对线程的管理和控制。这种方式使得线程的管理更加便捷,同时也遵循了代理模式的思想。

线程状态—五大状态

 

停止线程 

//测试stop
//1.建议线程正常停止--->利用次数,不建议死循环
//2.建议使用标志位--->设置一个标志位
//3.不要使用stop或者destory
public class TestStop implements Runnable{
    //1.设置一个标志位
    private boolean flag=true;
    @Override
    public void run() {
        int i=0;
        while (flag){
            System.out.println("run...Thread"+i++);
        }
    }
    //2.设置公开方法停止线程
    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) throws IOException {
        TestStop testStop=new TestStop();
        new Thread(testStop).start();

        for(int i=0;i<1000;i++)
        {
            System.out.println("main"+i);
            if(i==900){
                //调用stop方法切换标志位,让线程停止
                testStop.stop();
                System.out.println("线程停止了");
            }
        }


        System.in.read();
    }
}

 线程休眠_sleep

 线程礼让_yeild 

//测试礼让线程
public class TestYield {
    public static void main(String[] args) {
        MyYield myYield=new MyYield();
        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }
}

class MyYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "线程开始执行");
        Thread.yield();//礼让
        System.out.println(Thread.currentThread().getName() +"线程停止执行");
    }
}

线程强制执行_join

线程状态观测 

//观察测试线程的状态
public class TestState {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
            for(int i=0;i<5;i++){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("//");
        });


        //观察状态
        Thread.State state = thread.getState();
        System.out.println(state);  //new

        //观察启动后
        thread.start();//启动线程
         state = thread.getState();
        System.out.println(state);//run

        while(state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
            Thread.sleep(100);
            state=thread.getState();//更新线程状态
            System.out.println(state);//输出状态
        }
    }
}

 

 线程优先级

 守护(daemon)线程

线程同步

多个线程操作同一个资源。

同步方法及同步块

弊端

同步块

CopyOnWriteArrayList

java的JUC并发包下安全类型的集合

/**
 * 测试JUC安全类型的集合
 */
public class TestJUC {
    public static void main(String[] args) throws InterruptedException {
        CopyOnWriteArrayList<String> list=new CopyOnWriteArrayList<String>();

        for(int i=0;i<10000;i++){
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        Thread.sleep(3000);
        System.out.println(list.size());
    }
}

安全问题得到解决

 

 在其实现源码里面可以看见有两个JUC的关键词,volatile保证唯一,transient保证序列化的.

 死锁

死锁形成的四个条件: 互斥/请求与保持/不可剥夺条件/循环等待条件。 

Lock(锁)

ReentrantLock可重入锁类.

在CopyOnWriteArrayList里面就有这个类

 

/**
 * 测试lock锁
 */
public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2=new TestLock2();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
    }
}
class TestLock2 implements Runnable{
    int tickNums=10;

    //定义锁
   private final  ReentrantLock lock=new ReentrantLock();


    @Override
    public void run() {
        while(true){
            try{
                //此处加锁
                lock.lock();
                if(tickNums>0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(tickNums--);
                }else
                {
                    break;
                }
            }finally {
                //解锁
                lock.unlock();
            }
        }
    }
}

 

Synchronized和Lock的对比 

 线程协作和通信

生产者和消费者模式

 

管程法

 

代码实现网上大把.就是两个关键点,一个是消费数量的临界值,第二个就是wait 和notify的使用.

信号灯法

上面管程法用的是容器,这里用的是标志位,但是也相当于是容量为1的容器.

线程池

 就像是IO的缓冲池,Mybatis的缓存,数据库的连接池,JVM的常量池

 

public class TestPool {
    public static void main(String[] args) {
        //1.创建服务
        //参数为:线程池大小
        ExecutorService service= Executors.newFixedThreadPool(10);

        //执行
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        //2.关闭连接
        service.shutdown();
    }
}

class MyThread implements Runnable{


    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/934606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端vue2、vue3去掉url路由“ # ”号——nginx配置

文章目录 ⭐前言⭐vue2中router默认出现#号&#x1f496;在vue2项目中去掉&#x1f496;在vue3项目中去掉 ⭐vue打包 assetsPublicPath base 为绝对路径 /&#x1f496;vue2 配置 assetsPublicPath&#x1f496;vue3 配置 base&#x1f496;验证 ⭐nginx 配置&#x1f496; 使用…

ROS-3.ros创建工作空间和工作包

工作空间 工作空间(workspace)是存放工程开发相关文件的目录&#xff0c;目录里面包括 src &#xff1a;代码空间&#xff0c;ROS的catkin软件包&#xff08;源代码包&#xff09;build&#xff1a;编译空间&#xff0c;catkin&#xff08;CMake&#xff09;的缓存信息和中间…

关于事件回调机制

OVERVIEW 关于事件回调机制1.事件回调编程模式2.C中的事件回调编程模式函数指针回调函数对象回调 3.简单回调实例 关于事件回调机制 1.事件回调编程模式 当涉及到编程和软件开发时&#xff0c;事件回调是一种常见的编程模式。它用于处理异步事件和消息传递系统中的事件通知。 …

map set

✅<1>主页&#xff1a;我的代码爱吃辣&#x1f4c3;<2>知识讲解&#xff1a;C STL map&&set☂️<3>开发环境&#xff1a;Visual Studio 2022&#x1f4ac;<4>前言&#xff1a;map和set是C98就已经支持的两个搜索效率极高的容器&#xff0c;其底…

无涯教程-分类算法 - 随机森林

随机森林是一种监督学习算法&#xff0c;可用于分类和回归&#xff0c;但是&#xff0c;它主要用于分类问题&#xff0c;众所周知&#xff0c;森林由树木组成&#xff0c;更多树木意味着更坚固的森林。同样&#xff0c;随机森林算法在数据样本上创建决策树&#xff0c;然后从每…

高中信息技术教资考试模拟卷(22下)

2022 年下半年全国教师资格考试模考卷一 &#xff08;高中信息技术&#xff09; 一、单项选择题&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09; 1.2006 年 10 月 25 日&#xff0c;深圳警方成功解救出一名被网络骗子孙某…

认识Spring AOP面向切面编程

目录 一、面向切面编程思维&#xff08;AOP&#xff09; 二、AOP思想主要的应用场景 三、AOP术语名词介绍 四、Spring AOP框架介绍和关系梳理 一、面向切面编程思维&#xff08;AOP&#xff09; AOP&#xff1a;Aspect Oriented Programming面向切面编程 AOP可以说是OOP&a…

Linux 三剑客

grep grep主打的就是查找功能 &#xff0c;它能够在一个或者多个文件中搜索某一特定的字符模式。 grep的语法 grep [选项] 模式 文件名 先说选项&#xff1a; 1.选项 要么是正则要么是字符串 -c 列出共出现多少次 -i 忽略大小写 -n 在前面列出行号 -v …

分类模型评估指标——准确率、精准率、召回率、F1、ROC曲线、AUC曲线

机器学习模型需要有量化的评估指标来评估哪些模型的效果更好。 本文将用通俗易懂的方式讲解分类问题的混淆矩阵和各种评估指标的计算公式。将要给大家介绍的评估指标有&#xff1a;准确率、精准率、召回率、F1、ROC曲线、AUC曲线。 机器学习评估指标大全 所有事情都需要评估好…

Mycat之前世今生

如果我有一个32核心的服务器&#xff0c;我就可以实现1个亿的数据分片&#xff0c;我有32核心的服务器么&#xff1f;没有&#xff0c;所以我至今无法实现1个亿的数据分片。——MyCAT ‘s Plan 话说“每一个成功的男人背后都有一个女人”&#xff0c;自然MyCAT也逃脱不了这个诅…

AI自动驾驶也“区分人种”?有色人种和儿童面临更高碰撞风险

8月27日消息&#xff0c;随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;尤其是在自动驾驶汽车领域&#xff0c;这项技术给人类带来了巨大的便利。 然而&#xff0c;据最新的研究发现&#xff0c;自动驾驶汽车中的行人检测软件可能存在一些严重问题&#xff0c;…

章节 3:React.js基础 -《React.js手把手教程:从初学者到实战高手》- 第一部分:React.js基础

《React.js手把手教程&#xff1a;从初学者到实战高手》 第一部分&#xff1a;React.js基础 章节 3&#xff1a;React.js基础 在这一章中&#xff0c;我们将进一步了解 React.js 的基础知识。我们会从最基本的 React 组件开始&#xff0c;逐步引导你进入 React.js 的世界。 …

RocketMQ同步复制和异步复制

如果一个Broker组有Master和Slave&#xff0c;消息需要从Master复制到Slave上&#xff0c;有同步和异步两种复制方式。 1)同步复制 同步复制方式是等Master和Slave均写成功后才反馈给客户端写成功状态&#xff1b; 在同步复制方式下&#xff0c;如果Master出故障&#xff0c…

调用paddleocr接口实现文本检测与识别,并在图像中显示识别结果

目录 一、按照官网步骤安装paddlepaddle和paddleocr(paddlepaddle我安装的是cpu版本) 二、运行下面的脚本 三、图像结果 一、按照官网步骤安装paddlepaddle和paddleocr(paddlepaddle我安装的是cpu版本) doc/doc_ch/quickstart.md PaddlePaddle/PaddleOCR - Gitee.com 二、…

IDEA对Web和Tomcat的一些配置

这里只是做了自己学习中的一点记录&#xff0c;仅供参考哈&#xff01; 配置Tomcat Modules新增Web 新增module后新增Artifacts 新增Artifacts后Tomcat新增布署 将指定的module由普通java项目变成web项目 直接创建布署到Tomcat时所需要的Aritifacts包 配置Servlet的依赖包 配置…

初识【类和对象】

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的…

Java进阶篇--创建线程的四种方式

目录 继承Thread类 扩展小知识&#xff1a; Thread类的常见方法 Thread 类的静态方法 实现Runnable接口 使用Callable和Future创建线程 使用Executor框架创建线程池 继承Thread类 创建一个继承自Thread类的子类&#xff0c;并重写其run()方法&#xff0c;将相关逻辑实现…

Flink CDC数据同步

背景 随着信息化程度的不断提高&#xff0c;企业内部系统的数量和复杂度不断增加&#xff0c;因此&#xff0c;数据库系统的同步问题已成为越来越重要的问题。 缓存失效 在缓存中缓存的条目(entry)在源头被更改或者被删除的时候立即让缓存中的条目失效。如果缓存在一个独立的…

“返璞归真,数字排毒”,放下智能手机,美国功能手机卷土重来

近年来&#xff0c;智能手机的普及已经改变了人们的生活方式和沟通方式。然而&#xff0c;随着科技的不断进步和不断涌现的各种新应用程序&#xff0c;一些年轻人开始感到疲惫和厌倦。他们觉得智能手机带来了太多的干扰和依赖&#xff0c;也让人们容易沉迷于社交媒体和短视频。…

Rabbitmq的Federation Exchange

(broker 北京 ) &#xff0c; (broker 深圳 ) 彼此之间相距甚远&#xff0c;网络延迟是一个不得不面对的问题。有一个在北京的业务(Client 北京 ) 需要连接 (broker 北京 ) &#xff0c;向其中的交换器 exchangeA 发送消息&#xff0c;此时的网络延迟很小&#xff0c;(C…