JAVA基础(JAVA SE)学习笔记(十)多线程

news2024/11/17 10:50:54

 前言 

1. 学习视频:

尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)_哔哩哔哩_bilibili

2023最新Java学习路线 - 哔哩哔哩

第三阶段:Java高级应用

9.异常处理

10.多线程

11.常用类和基础API

12.集合框架

13.泛型

14.数据结构与集合源码

15.File类与IO流

16.网络编程

17.反射机制

18.JDK8、17 新特性

正文

10.多线程

10.1 多线程的理解

程序、进程、线程区分:

举例:

线程调度:

10.2 多线程的创建方式

10.2.1 多线程的创建方式一:继承Thread类

举例:创建一个分线程1,用于遍历100以内的偶数。

可以看到创建的线程和main的线程在交互执行。还可以看到线程名如上。

 System.out.println(Thread.currentThread().getName()+":"+i+"***********");
 System.out.println(Thread.currentThread().getName()+":"+i);

例二:

创建Thread类的匿名子类的匿名对象:

10.2.2 多线程的创建方式二:实现Runnable接口(建议使用方式)

或:

声明了两个线程,但是只声明了一个EvenNumberPrint类,相当于共享数据。

相当于 代码逻辑(新建线程执行任务)  和 数据(一个EvenNumberPrint类)的分离

两种创建线程的方式对比:

练习题:

10.3 继承Thread类的常用方法

10.3.1 构造器

Thread中:

使用举例:

10.3.2 常用方法

使用举例:

  

10.3.3 优先级(Priority)

10.3.4 多线程的优点

10.4 生命周期

现在JDK17,线程的状态如下:

新建、准备、运行、阻塞(锁阻塞、无限等待、计时等待)、死亡。

public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,WAITING,TIMED_WAITING,
        TERMINATED;
    }

运行(Runnable):Ready、Running。

阻塞分为三种状态:

        锁阻塞(BLOCKED)、无限等待(WAITING)、计时等待(TIMED_WAITING)。

死亡(terminated)。

10.5 买票案例,引出线程安全问题,引出同步机制

线程不安全,已卖过的票,还会被再次售卖。加上static共享变量,也不行。

10.5.1 使用synchronized同步机制处理线程安全问题

同步代码块:

同步监视器用在循环内部,保证了每次售票时,三个线程随机排队进入监视器内部,执行买票,模拟了三个窗口售票。如果把循环体整个加入监视器,则三个窗口只随机排队一次,然后售空才能结束循环,进入下一次排队,不符合实际。

使用快捷键,生成环绕方式synchronized监视器,然后直接在小括号内写this。

在继承Thread类后,假如声明三个子类对象,要用static修饰作为同步监视器的Object类,使三个子类共享数据。保证唯一性,使用当前类.class,即Window.class

同步方法:

 public static synchronized void xxx(){ //操作共享数据的代码  }

此时的同步监视器,默认的就是this(调用者)。在下列代码中,this是唯一的,因为只新建了一个SaleTicket2类的对象。三个线程的共享对象是同一个。

继承:

如下:三个线程,没有共享对象,是三个不同对象。this有三个。

synchronized的优缺点:

习题:

sleep在哪执行,哪个线程就进入阻塞。(主线程内执行sleep方法,主线程阻塞5秒)

10.5.2 线程安全的懒汉式

两个线程获取Get方法创建单例的实例对象,线程不安全,创建了两个实例对象。需要添加Synchronized,得到同步方法。

方法二:同步代码块   和   方式三:同步代码块 优化(进监视器之前多加一层判断,效率更高)

使用volatile避免指令重排:

将instance声明为volatile,可以避免在第一个线程正在创建的时候,还没有地址,第二个线程判断第一个线程已经非空,就返回instance,造成返回空值。

10.5.3 线程的同步机制带来 死锁问题

死锁示例:

不睡眠,则很快执行,没有死锁。睡眠诱发死锁概率提高,发现有死锁问题,不能运行出结果。

10.5.4 使用jdk5.提供的Lock锁的方式 处理线程安全问题

目前创建ReentrantLock(重新re进入entrance 锁lock)的对象:

   //private:外部不可访问;
   //static:几个线程共用同一个锁;
   //final:赋值之后不可修改。
   private static final ReentrantLock lock = new ReentrantLock();

检查'在使用阻塞等待获取锁的方式中,必须在try代码块之外,并且在加锁方法与try代码块之间没有任何可能抛出异常的方法调用,避免加锁成功后,在finally中无法解锁
说明一:如果在lock方法与try代码块之间的方法调用抛出异常,那么无法解锁,造成其它线程无法成功获取锁。
说明二:如果lock方法在try代码块之内,可能由于其它方法抛出异常,导致在finally代码块中,unlock对未加锁的对象解锁,它会调用AQS的tryRelease方法(取决于具体实现类),抛出IllegalMonitorStateException异常。
说明三:在Lock对象的lock方法实现中可能抛出unchecked异常,产生的后果与说明二相同。 java.concurrent.LockShouldWithTryFinallyRule.rule.desc

Positive example:
    Lock lock = new XxxLock();
    // ...
    lock.lock();
    try {
        doSomething();
        doOthers();
    } finally {
        lock.unlock();
    }

synchronized不管是同步代码块还是同步方法,都需要在结束一对{}之后,释放对同步监视器的调用。Lock是通过两个方法控制需要被同步的代码,更灵活一些。

Lock作为接口,提供了多种实现类,适合更多更复杂的场景,效率更高。

在JUC会详细讲解LOCK。

10.6 线程的通信

wait()和notify():

能不能使下面两个线程交替打印1~100之间的数:

线程一执行到notify(),不需要唤醒,继续执行,然后打印数字,执行wait()。

线程二执行到notify(),本身不需要唤醒,但唤醒线程一,线程二继续执行,打印数字,执行wait()。线程一被唤醒后继续执行wait()后面的代码else,然后重新执行到notify(),本身不需要唤醒,但唤醒线程二。

wait()和sleep()的区别:

习题:

10.7 多线程的创建方式三:实现Callable接口(JDK5.0新增)(了解)

t1.start()执行之后,分线程开始打印1~100以内的偶数,主线程开始去调用futureTask.get()方法,打印总和。若分线程阻塞(例如加上:Thread.sleep(1000);),则主线程获取的总和结果就会不正确。

其实不是这样的,t1.start()执行之后,分线程开始打印1~100以内的偶数,主线程开始去调用futureTask.get()方法会暂时阻塞,等待return操作的结果。而return操作需要等分线程打印1~100以内的偶数执行完毕,然后才return,主线程才会打印总和。

10.8 多线程的创建方式四:使用线程池(开发中使用)

总结:

栈管运行,堆管存储。所以线程在栈里。

非静态方法同步监视器,默认的就是this(调用者对象)。

非静态方法同步监视器,默认的就是this(调用者对象)。如下,t1线程进入了一个对象SaleTicket1的synchronized方法之后,其他线程例如t2就还能进入对象SaleTicket1的其他方法,因为两个同步监视器的this分别是不同的实例对象s和s1。而且都是唯一的。但是t3和t1的this是同一个,所以不能访问此对象实例s的其他方法。发挥了同步代码块的作用,避免了线程安全问题。

阻塞还可能是sleep()、wait()、join()、suspend()了。

自己练习一下。

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

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

相关文章

浅谈js代码的封装方法(2023.10.30)

常见的js代码封装方法 2023.10.30 需求1、js代码封装的优缺点2、js代码封装方式2.1 方式一:function function declarations2.1.1 示例 2.2 方式二:class2.2.1 class declarations2.2.2 Class expressions 2.3 变量函数2.4 变量闭包匿名函数2.5 闭包函数…

TiDB 企业版全新升级,平凯数据库核心特性全解读

作为 TiDB 企业版的全新升级,平凯数据库一经推出便广受媒体及用户关注。 近日,平凯星辰首席科学家丁岩在“平凯数据库全解读”活动中,首次详细介绍了平凯数据库的核心能力。 本文为丁岩演讲实录全文,为方便阅读,已做部…

[激光原理与应用-72]:PLC架构与工作原理

目录 一、PLC简介 1.1 概述 1.2 基本组成 1.3 常见的PLC品牌比较 二、PLC程序执行原理 2.1 PLC有操作系统吗? 2.2 PLC程序执行 2.3 PLC编程语言 2.4 PLC编程过程 三、PLC编程工具 3.1 编程工具 四、PLC与工控机协同 4.1 PLC需要配置工控机吗&#xff1…

构建Web UI自动化测试平台

您好, 如果喜欢我的文章或者想上岸大厂,可以关注公众号「量子前端」,将不定期关注推送前端好文、分享就业资料秘籍,也希望有机会一对一帮助你实现梦想 前言 什么是前端UI自动化测试平台?由于部门的业务域非常广&…

HCIP——MGRE实验

一、实验要求 1.R5为ISP,只能进行IP地址配置;其所有地址均为公有IP地址 2.R1和R5间使用PPP的PAP认证,R5为主认证方; R2与R5之间使用PPP的chap认证,R5为主认证方; R3与R5之间使用HDLC封装。 3.R1/R2/R3…

纪念基于JavaScript 实现的后台桌面 UI 设计

目录 前言 C/S 到 B/S ASP Builder 的诞生 关于 Craneoffice.net 开发环境配置 后台界面的 UI 区域要素 桌面系统的想法和设计 搜索引擎 导航面板 快捷访问 二级导航 小组件及其它 设置桌面壁纸 小时钟 附件小程序 计算器界面设计 日历与任务 系统设置 天气小…

ChineseChess.2023.10.30.02

中国象棋模拟器 接下来不管黑怎么走都是开始杀【卒】 中国象棋残局模拟器ChineseChess.2023.10.30.02_桌游棋牌热门视频

二叉搜索树的最小绝对差[简单]

优质博文:IT-BLOG-CN 一、题目 给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,其数值等于两值之差的绝对值。 示例 1: 输入:root [4,2,6,1,3] 输出:1 示例 …

K8s集群

统一时间:ntpdate(都做) ntpdate -b ntp1.aliyun.com */1 * * * * /usr/sbin/ntpdate -b ntp1.aliyun.com systemctl status docker vi /etc/docker/daemon.json systemctl restart docker m: vim kubernetes.sh cat >> /etc/yum.repos.d/kubernetes.repo…

Unity中Shader的全局照明简介

文章目录 前言一、什么是全局照明GI1、全局照明(Global Illumination),简称GI2、指既考虑场景中直接光源的光照(Direct Light)又考虑经过场景中其他物体反射后的光照(Indirect Light)的一种渲染…

小红书关键词类型有哪些,如何布局搜索流量?

通过搜索关键词寻找到关注的内容,是大部分小红书用户的浏览习惯。因此作为品牌方,找准搜索的关键词,并合理嵌入内容中,就显得尤为重要。今天为大家分享下小红书关键词类型有哪些,如何布局搜索流量? 一、关键…

加速生态培育,国产CPU走到哪了?

国产大飞机C919的成功商飞,证明我国已经拥有了设计制造大飞机的能力。继高铁、盾构机等多个领域后,再次证明即使是技术后来者,通过在起步阶段引进关键技术,吸收消化后,自主研发不断发展前行,这条“引进吸收…

智慧粮库挡粮门异动监测

我国以往粮食收储设施比较老化,如何减少粮食在存储运输过程中的人为因素,确保粮食安全,成为亟待解决的问题,为了减少粮食的损失,“智慧粮库”的建设在我国有着重要意义。“智慧粮库”充分利用物联网、人工智能等技术&a…

自定义点云的数据类型PointXYZIRT

PCL支持的点云数据类型有PointXYZ、PointXYZI等,但是对于速腾、Velodyne等激光雷达的原始点云中还包含了激光点线号ring和每个激光点的时间戳信息,在读取该类点云时需要基于PCL库自定义点云格式才能读到原始点云的所有信息,以速腾激光雷达点云…

回归测试:在不断变化的环境中确保软件的稳定性

软件开发是一个复杂的过程,需要不断变化和更新以满足客户不断变化的需求,但它们也可能产生新问题或导致旧问题重新出现。这就是回归测试的用武之地——它是在不断变化的环境中确保软件稳定性的重要组成部分。 在这篇文章中,我们将深入探讨什…

开放式耳机推荐排行榜、开放式耳机性价比推荐

随着无线耳机越来越普及,人们对于耳机的要求也越来越高。传统的入耳式耳机虽然音质好,但是长时间佩戴容易引起耳部不适,甚至可能导致听力损失。为此大家都开始选择入手舒适、安全的开放式耳机,现在耳机市场,各种品牌、…

*VS Code中的Ajax

下载插件并使用 下载插件,开放一个端口给要加载的资源,解决跨域问题,没有后端接收数据,用来做小模块很合适 建立文件夹,文件夹下放入jquery插件和json文件 data.json {"total": 4,"data": [{"name&qu…

11、SpringCloud -- 利用redis优化查询秒杀商品的数据(就是可以把商品数据先存到redis中)

目录 秒杀商品数据存到redis中并查询需求hash理解代码:RedisService商品数据初始化:查询 测试: 秒杀商品数据存到redis中并查询 需求 利用redis优化查询秒杀商品的数据,就是可以把商品数据先存到redis中,要查的时候先…

springboot整合日志,并在本地查看

目录 1.导入依赖 2.编写配置 3.使用 4.验证 5.打印错误信息 1.导入依赖 <!-- logback&#xff0c;向下兼容log4j,还支持SLF4J--> <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId> </depen…

IPv6地址配置方式

IPv6地址分类 IPv6地址分为单播地址、任播地址&#xff08;Anycast Address&#xff09;、组播地址三种类型。和IPv4相比&#xff0c;取消了广播地址类型&#xff0c;以更丰富的组播地址代替&#xff0c;同时增加了任播地址类型。 单播地址 IPv6单播地址标识了一个接口&…