7:Multithreading-Java API 实战

2023-05-16

目录

  • 1. 问题的提出
  • 2. 核心数、进程、线程
  • 3. 进程和线程的区别以及对应应用
  • 4. 多线程程序含义、多线程的作用
  • 5. 多线程的执行过程
  • 6. Runnable
  • 7. 简化操作以及线程名
  • 8. 抢购鞋——多线程案例
  • 9. 后台、守护进程的提出
  • 10. 匿名内部类创建多线程——你们老师喜欢的
  • 11. 发现问题,提出synchronized的概念和用途
  • 12. synchronized同步方法
  • 13 Lock、ReentrantLock同步锁
  • 14. Unlock遗留问题,释放锁
  • 15. 浅谈synchroized和Lock的区别
  • 16. Thread API说明
  • 17. CPU线程调度、Priority线程优先级、优先级常量、剩余小问题
  • 18. join线程插队
  • 19. sleep线程休眠
  • 20. yield线程让步
  • 21. 线程状态?嗯,还是来玩一盘游戏吧!
  • 22. 发现实际问题,抛出线程通信的含义
  • 23. 线程的通信:wait和notify
  • 24. notifyAll
  • 25. 提及Process进程。点到为止,章节结束语和建议。

1. 问题的提出

一台计算机为何能够执行多个程序?它们是怎么执行多个程序的?

  • 电脑可以同时做很多事情,一边聊天,一边听歌,一边上网查资料等
  • 原因是电脑有多个核心(脑子),一个核心可以做一件事情,多个核心就可以做多件事情
  • 而多线程就是一台电脑,CPU可以同时运行两个程序(表面上),实际上是进程切换的快,第一个进程打开,第二个进程挂起,给你一种错觉

在这里插入图片描述
例如CPU的6核12线程,就相当于有6个工人去运行进程

在这里插入图片描述

2. 核心数、进程、线程

  • 一个核心下有多个进程,而一个进程下又会有多个线程

3. 进程和线程的区别以及对应应用

进程和线程的区别

  • 线程只是一个进程中不同执行的路径
  • 进程与进程之间不会相互影响,因为它们是占有独立内存的
  • 而线程是占用共同的内存,所以一个线程出问题,那这个进程下的线程都会出问题
  • 多进程的程序要比多线程的程序健壮,而多线程运行效率更高,但是线程不能独立执行,必须依存在应用程序中,操作系统不会把线程看作多个独立应用
  • 但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。例如很多人共同抢一双鞋,就要用到多线程

并发与并行

  • 并发(Concurrent)指一个CPU需要进行多个进程,这样就需要不停的切换,让进程不断的交替执行
  • 并行(Parallel)指多个CPU同时执行多个进程

4. 多线程程序含义、多线程的作用

创建多线程DemoThread类,Alt+Insert调出Generate选择Override Methods

在这里插入图片描述
选择run():void
在这里插入图片描述
mainThreadDemoThread两个字符串交替执行

在这里插入图片描述
如果用.run()的话会出现问题,死循环一直在跑,用.start()可以多开启一个线程,然后去自动调用.run(),再继续进行当前线程
在这里插入图片描述

显示的结果是两个死循环的内容在交替执行,其原因就是使用了.start()后两个线程一直在执行

5. 多线程的执行过程

多线程的执行方式

  • 一般的程序是从main出发,直线向下进行,只有一条主线
  • 多线程在main主线程序遇到线程程序时会转到线程程序,并返回到主线程序中,这样main程序和线程程序同时执行

在这里插入图片描述

6. Runnable

前面我们创建线程单继承了Thread,无法继承别的类,因为Java不支持多继承

使用Runable接口来创建线程,要使用其方法,必须创建Thread对象实现

在这里插入图片描述

Ctrl + 左键查看Thread源码
在这里插入图片描述

源码中,Thread类就是实现了Runnable接口,而在Thread的构造方法中也有许多方法函数需要传递Runnable接口类型

在这里插入图片描述

而我们在主函数中实现的应该是第一种传递方式,Thread的构造方法还有很多方式,这些构造函数都有一个特点就是全部使用init这个方法对线程进行实现

init源码的变量注释及源码

  • 在原始的init中名字是不能为空的,如果名字为空会报空指针异常,但是在其他的函数中,如果程序员不给thread.name赋值的话也可以自动生成一些值
  • 涉及线程组相关的安全问题
  • 变量的赋值和其他函数的初始化相关

在这里插入图片描述
在这里插入图片描述

下面init方法是对上面的函数的衍生,是构造方法中使用的初始方法
在这里插入图片描述

7. 简化操作以及线程名

Thread源码里面有传线程名的构造方法,要在原来线程类中自动获取我们在主线程中设置的名字,使用Thread.currentThread().getName()方法,.currentThread()是指当前线程,.getName()是指获取名字

在这里插入图片描述

8. 抢购鞋——多线程案例

两种创建线程的方式,一种使用继承,一种使用接口实现,解决了线程名的问题,接下来我们模拟一个多线程的抢鞋程序

抢鞋的逻辑代码涵盖在线程当中,假设有10双鞋,有三个人来抢,一个线程就是一个用户,所以这就有三个名称不一样的线程名

使用Runnable接口创建

在这里插入图片描述

9. 后台、守护进程的提出

电脑任务管理器

  • Apps是前台进程,Background processes是后台进程也叫守护进程,这些进程在电脑开机时就被启动,这样电脑才能正常且安全的运作起来,在程序中也是同理
  • 与进程同理,前台线程为用户提供服务,也有后台线程为前台线程提供的服务进行保护或者守护

在这里插入图片描述

后台线程的创建过程

  1. 创建一个DaemonThread,实现Runnable接口

  2. 重写run()方法

  3. 在运行类中创建先一个DaemonThread,再用 Thread 用来实现DaemonThread

  4. 最后调用setDaemon(true) 设置成后台守护线程,.start()开启线程
    在这里插入图片描述

10. 匿名内部类创建多线程——你们老师喜欢的

Runnable接口进行匿名处理

在这里插入图片描述

11. 发现问题,提出synchronized的概念和用途

现实情况中,抢鞋肯定是有延时操作的,如果我们用.sleep()设置每次抢鞋之间的间隙,会产生了一个问题,就是线程不同步导致线程不安全,两个人同时抢了第7双鞋

在这里插入图片描述

解决这个问题要用到线程同步,及时更新数据,即创建一个synchronized锁对象,同步数据
在这里插入图片描述

12. synchronized同步方法

如何理解锁呢?当用户一抢到第一双鞋时,锁住第一双鞋,其它用户就无法抢了
在这里插入图片描述

synchronized可以创建成一个同步方法,将同步代码块抽离出来
在这里插入图片描述

13 Lock、ReentrantLock同步锁

synchronized与reentrantLock区别

  • synchronized 不需要用户去手动释放锁,代码执行完后系统会自动让线程释放对锁的占用
  • reentrantLock则需要用户去手动释放锁,如果没有手动释放锁,就可能导致死锁现象

在这里插入图片描述

14. Unlock遗留问题,释放锁

释放reentrantLock锁,try catch要放在if外面,最后finally调用reentrantLock.unlock()方法

在这里插入图片描述

15. 浅谈synchroized和Lock的区别

  • JDK1.5中,synchroized是重量级操作,性能低效,Lock性能高,更稳定
  • JDK1.6中,synchroized加入很多优化,更加稳定了

锁的释放

  • synchronized以获取锁的线程执行完同步代码,如果线程执行发生异常,jvm会让线程释放锁

  • Lockfinally中必须释放锁,不然容易造成线程死锁

死锁产生

  • synchronized在发生异常时候会自动释放占有的锁,不会出现死锁
  • Lock发生异常时候,不会主动释放,必须手动unlock来释放锁,可能引起死锁的发生

用法

  • synchronized在需要同步的对象中加入,可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象

  • Lock一般使用ReentrantLock类做为锁,通过lock()加锁和unlock()解锁指出,在finally中写unlock()防止死锁

16. Thread API说明

参考:Thread (Java Platform SE 7 ) - Oracle

17. CPU线程调度、Priority线程优先级、优先级常量、剩余小问题

CPU线程调度

  • 每一个线程的优先使用权都是系统随机分配的,人人平等,谁先分配到谁先用
  • 可以设置优先级赋予某一个线程拥有至高适用权,最高为10,最低为1,默认为5,Java可以抢占CPU
    在这里插入图片描述

线程1-10中,main()主线程的value = 5,创建 MaxPriorityThread 类和MinPriorityThread来查看线程执行顺序

在这里插入图片描述
.start()前面加优先级.setPriority()方法即可越权
在这里插入图片描述

但有时会发现优先级没有调换过来,是操作系统的原因,程序执行太快了没有反应过来,还没调度程序就结束了
在这里插入图片描述

18. join线程插队

.join()方法可以抢占优先级,实现插队
在这里插入图片描述

19. sleep线程休眠

还是上一个例子,使用.sleep()方法休眠后,thread_1线程插队时,会等待1000毫秒再打印出结果
在这里插入图片描述

20. yield线程让步

.yield()方法可以实现线程让步,让其它线程执行,thread_1输出一次的时候给thread_2让步了,有时程序运行的太快了,以至于还没打印出让步输出,thread_2已经输出完毕了

在这里插入图片描述

21. 线程状态?嗯,还是来玩一盘游戏吧!

Java中线程的状态分为6种–以斗地主为例

1.新建(NEW)-新建一局游戏

2.可运行(RUNNABLE)-初始状态是可运行的

3.阻塞(BLOCKED)-谁出牌谁获得一个锁,导致阻塞,出好牌则疏通阻塞

4.等待(WAITING)-不出牌的等待通知

5.计时等待(TIMED_WAITING)-出牌时,其他人计时等待超时或通知

6.终止(TERMINATED)-游戏结束

在这里插入图片描述

参考: Java线程的6种状态及切换(透彻讲解)

22. 发现实际问题,抛出线程通信的含义

线程优先级

  • Win10任务管理器中,线程有6个优先级设置
  • 线程的调度目的就是通知另一个线程去执行,也有其它办法去通知
    在这里插入图片描述

23. 线程的通信:wait和notify

线程通信,即等待唤醒机制

  • 最简单的例子如Producer生产者与Customer消费者和Condom产品的关系
  • 当产品Condom产品生产出来之后,消费者购买完,需要联系Producer厂商继续生产
  • .notify() 方法用于唤醒一个在此对象监视器上等待的线程
  • 一个线程在对象监视器上等待可以调用 .wait() 方法

在这里插入图片描述

在这里插入图片描述

24. notifyAll

.notifyAll()方法用于唤醒在该对象上等待的所有线程

25. 提及Process进程。点到为止,章节结束语和建议。

多线程掌握基础,当学习到框架时,需要深入并发编程

参考:操作进程拓展Class ProcessBuilder

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

7:Multithreading-Java API 实战 的相关文章

随机推荐

  • 3:步入Linux的世界-步入Linux的现代方法

    目录 3 1 Linux究竟需要我们学习什么 xff1f Linux四大组成部分3 2 Linux是命令还是图形界面 xff1f GUI 是什么 xff1f 那GNU是什么东西 xff1f GNU Linux 和Linux有什么区别 xff
  • Linux中 sudo su 和 su 区别

    su 直接切换root用户 xff0c 需输入root密码ubuntu xff0c 默认没有设置root密码 xff0c 使用sudo passwd root设置root密码 sudo su 当前用户暂时申请root权限 xff0c 需输入
  • Python 使用 Qt5 实现水平导航栏

    在 Qt5 中可以使用 QWidget 包含两个水平布局 xff0c 通过点击水平布局里的按钮 xff0c 实现下标滑动与页面的切换 可以按照以下步骤来实现上面图片中的功能 xff1a 导入必要的 Qt 包 xff1a span class
  • OOP上半部分-Java与生活

    目录 1 1 1 问题产生和引导1 1 2 烦人1 1 3 变换思维1 1 4 规划明确目标站在更高层次思考问题1 1 5 上代码 xff0c 设计体验面向对象编程 xff0c 实例和对象1 1 6 去你md成员变量行为类和this1 1
  • Centos7 搭建Jupyter NoteBook教程

    目录 1 Anaconda31 1 下载1 2 安装 2 环境配置2 1 添加PATH到 root bashrc文件中2 2 激活配置的环境变量 3 搭建虚拟环境3 1 创建虚拟环境3 2 开启环境3 3 查看已有的虚拟环境 4 jupyt
  • OOP下半部分-Java与生活

    目录 面向对象三大特性 xff1a 封装 继承 多态2 1 1 需求重定义2 1 2 继承2 2 2 饿狼传说之多层继承2 2 3 方法的重写2 2 4 super啃老2 2 5 啃老啃到彻底2 2 6 final2 2 7 提出新的问题2
  • Centos7 搭建单机Spark分布式集群

    目录 1 JDK Hadoop Spark安装与配置1 1 解压包1 2 配置环境变量 2 Scala安装与配置2 1 Scala安装2 2 配置环境变量 3 配置集群3 1 配置sprak3 2 启动spark 4 问题 xff1a 虚拟
  • 面向对象大胆向前 Java API 实战

    目录 0 xff1a Base API 引言API的定义和用处ScannerNumberMathRandomThreadLocalRandomDateDateFormat和SimpleDateFormatCalendarSystem 详见
  • Yeats_Liao的书单

    计算机软件类 大话计算机 冬瓜哥 架构师的自我修炼 李智慧 图解算法 xff1a 使用C语言 吴灿铭 胡昭民 编程原则 马克思 卡纳特 亚历山大 啊哈 xff01 算法 啊哈磊 Java Web框架开发技术 Spring 43 Spring
  • 0:Base API-Java API 实战

    目录 0 1 引言0 2 API的定义和用处0 3 Scanner xff08 普通类 xff09 0 4 Number xff08 包装类 xff09 0 5 Math xff08 工具类 xff09 0 6 Random xff08 父
  • 黑客与画家 [美] Paul Graham 读书摘录

    充分理解程序员带来的美和智慧 xff0c 这是本书做到的 P15 为什么书呆子不受欢迎 xff1f 平庸带来的严重后果 xff0c 直接导致学生的叛逆心理 我误解最深的一个词是 老成 tact 成年人使用这个词 xff0c 含义似乎就是 闭
  • 教育的真谛 [英] 尼古拉斯·泰特 读书摘录

    自柏拉图以来 xff0c 教育的目的与性质始终是西方哲学传统关注和探讨的问题 纵览2500年来的思想成果 xff0c 作者尼古拉斯 泰特博士在 教育的真谛 xff1a 伟大思想家的观点及其现实意义 中指出 xff0c 人类的教育活动至少应包
  • 1:Unit test and main function-Java API 实战

    目录 1 抛出企业问题 xff0c 脱离main测试 xff0c 模块化编程2 Junit单元测试的含义和用途3 怎么获取各种Jar包 xff1f Maven Repository 获取各类各个版本的jar xff0c 这就是仓库 脱离老师
  • CentOS 安装 Samba服务器(多用户组、多用户有不同的访问权限)

    增加smb用户 root 64 localhost sir01 smbpasswd a linuxsir 查看 smb 现有用户 pdbedit L 验证用户登录文件夹 smbclient 192 168 101 93 forlder U
  • 2:StringBuilder-Java API 实战

    目录 1 String存在的问题2 Stringbuilder以及链式调用的含义 1 String存在的问题 认识String 字符串广泛应用在编程中 xff0c 在 Java 中字符串属于对象 xff0c Java 提供了 String
  • 3:Throwable-Java API 实战

    目录 1 异常的介绍2 异常举例以及解决常见错误bug方案3 RuntimeException4 trycatch作用 xff0c 闲扯淡诱骗毕业设计5 NullPointerException空指针异常6 throws7 throws和t
  • 4:File-Java API 实战

    目录 1 引言2 绝对路径和相对路径 xff1f 先学送快递吧 xff01 3 绝对路径4 相对路径5 File类6 Linux上的绝对路径有所不同 1 引言 文件要区别绝对路径和相对路径 xff0c 在Win系统中的文件路径和Linux
  • 5:IO Stream-Java API 实战

    目录 1 相对论和IO流之说2 汉语文学理解IO流3 图解IO流4 俩亲爹 xff1a InputStream和OutPutStream5 FileInputStream字节流读取文件6 FileOutPutStream字节流写入文件7 b
  • 6:CharSet-Java API 实战

    目录 1 阶段2 字符集编码吹X3 转换字符编码 1 阶段 Java NIO File Java NIO中的Files类 xff08 java nio file Files xff09 提供了多种操作文件系统中文件的方法 Java File
  • 7:Multithreading-Java API 实战

    目录 1 问题的提出2 核心数 进程 线程3 进程和线程的区别以及对应应用4 多线程程序含义 多线程的作用5 多线程的执行过程6 Runnable7 简化操作以及线程名8 抢购鞋 多线程案例9 后台 守护进程的提出10 匿名内部类创建多线程