当前位置: 首页 > article >正文

java多线程学习笔记

文章目录

    • 关键词
    • 1.什么是多线程以及使用场景?
    • 2.并发与并行
    • 3.多线程实现
      • 3.1继承 Thread 类实现
      • 3.2Runnable 接口方式实现
      • 3.3Callable接口/Future接口实现
      • 3.4三种方式总结
    • 4.常见的成员方法(重点记忆)9
      • 4.1setName/currentThread/sleep要点
      • 4.2线程的优先级10档(priority)
      • 4.3守护/备胎线程(Daemon)
      • 4.4礼让/出让继承(yield又得)了解
      • 4.5插入线程(join)了解
    • 5.线程的生命周期
    • 6.线程的安全问题(synchronized)
      • 6.1产生的问题:
      • 6.2为什么产生:
      • 6.3解决方法:
        • 6.3.1同步代码块
        • 6.3.2同步方法
      • 6.4扩展
    • 7.lock锁(jdk5出现)
    • 8.死锁
    • 9.等待唤醒机制(生产者和消费者)
      • 9.1思路分析
      • 9.2常见方法(单个桌子实现)
      • 9.3吃货与桌子代码
      • 9.4厨师和main代码
      • 9.5阻塞队列实现
        • 厨师吃货类
        • 测试类
    • 10.java线程状态

关键词

3.1 Thread

3.2 Runnable

3.3 Callable/FutureTask

4 setName()、getName()、currentThread()、sleep()、

setPriority()、getPriority()、setDaemon()、yield()、join()

6 synchronized

7 static Lock lock = new ReentrantLock();

9.2 wait()、notify()、notifyAll()

9.5 ArrayBlockingQueue【put、take】、LinkedBlockQueue

1.什么是多线程以及使用场景?

应用软件种互相独立的,可以同时运行的功能,就形成了多线程

例子:360杀毒软件中,有木马查杀、电脑清理、系统修复、优化加速等可以同时运行的功能

场景:

1.拷贝迁移大文件的时候,多线程可以运行其他功能

2.加载大量资源文件,例如打开游戏时,加载资源文件,加载这些的同时,检查游戏版本,播放背景音乐

2.并发与并行

并发:同一时刻,多条指令在单个CPU交替执行

并行:同一时刻,多条指令在多个CPU同时执行

3.多线程实现

3.1继承 Thread 类实现

每一个创建出来的线程都是独立的,需要共享数据用static修饰常量

从这里可以看出代码是交替执行的(并发)

3.2Runnable 接口方式实现

由于是以参数的形式创建的线程,所以只会创建一次

3.3Callable接口/Future接口实现

3.4三种方式总结

前两种无法获取多线程运行的结果,由于重写的run方法是void,没有返回值,第三种有返回值

4.常见的成员方法(重点记忆)9

4.1setName/currentThread/sleep要点

4.2线程的优先级10档(priority)

关键词:抢占式调度(随机),非抢占式调度

优先级越高,抢到CPU执行权的(概率)越高

参考代码:

4.3守护/备胎线程(Daemon)

备胎线程陆续结束,不会全部执行完毕

应用场景

线程1聊天窗口,要是关闭了,那么线程2没有执行的必要了,所以线程2可以设置成守护线程

4.4礼让/出让继承(yield又得)了解

主要作用:让线程的执行尽可能均匀一点

4.5插入线程(join)了解

5.线程的生命周期

6.线程的安全问题(synchronized)

6.1产生的问题:

1.三个窗口买票共100张,看作三个线程,进行卖票,由于线程独立,导致卖了300张票

2.线程设置static修饰共享,可是依然会有超出范围的票和重复的票被卖出

6.2为什么产生:

**问题1:**例如,设置了sleep,在if条件中满足的都会进入执行代码,线程1执行了+1操作,刚到打印语句,线程2也执行了+1操作,此时,值就是2,那么线程1打印的值为2,线程2也是2

**问题2:**三个线程进入if的时候都满足条件,线程1为99时进入if,没有执行打印语句的时候,++就是100,此时,还没有打印,线程2进入++就是101,再线程3进入就是102

6.3解决方法:

6.3.1同步代码块

把操作共享的代码锁起来,也就是给代码块上锁

**细节1:**synchronzied要写在while里面,不然线程1抢到执行权,那么就会上锁,线程2 3无法执行,线程1解锁,那么100张票已经卖完

**细节2:**锁对象要是唯一的(Object,字节码对象),如果是两把不同的锁,A锁打开进入后关闭,线程1没有来就会一直锁着,线程2进不去,要是有B锁作为锁对象,那么B锁未被占用可以打开进入执行,那么上锁就没有意义了,eg:用this作为锁对象,那么锁就是不唯一的,

6.3.2同步方法

把synchronized关键字加到方法上,配合Runnable接口使用可以不考虑锁对象是否唯一

6.4扩展

StringBuilder:单线程使用,多线程不安全

StringBuffer:多线程使用,相比StringBuilder,该类的方法都是用synchronized进行了同步

7.lock锁(jdk5出现)

用于解决synchronized关键字不能手动枷锁的问题

标准写法

由于线程1执行到break会跳出循环,那么可定不会执行到释放锁的操作,那么线程永远不会停止,我们就可以将lock.unlock()写在finally方法体中,finally会在前面两个执行完成后执行,无论try是否抛出异常,或者catch是否捕获异常

8.死锁

操作系统学过,循环等待,不可剥夺,避免写这样的代码即可

9.等待唤醒机制(生产者和消费者)

9.1思路分析

9.2常见方法(单个桌子实现)

9.3吃货与桌子代码

9.4厨师和main代码

9.5阻塞队列实现

阻塞队列底层已经有锁,不需要再枷锁

厨师吃货类

测试类

10.java线程状态

是没有运行状态的,当线程抢到cpu执行权的时候,就会交给操作系统去管理,jvm就不管了


http://www.kler.cn/a/523133.html

相关文章:

  • PostgreSQL 约束
  • 网易云音乐歌名可视化:词云生成与GitHub-Pages部署实践
  • java 字符串日期字段格式化前端显示
  • 2024收尾工作
  • springboot跨域配置
  • 初阶1 入门
  • golang中的包管理-上--简介
  • 视频拼接,拼接时长版本
  • JavaScript反爬技术解析与应对
  • 蓝桥杯练习日常|递归-进制转换
  • SpringBoot或SpringAI对接DeekSeek大模型
  • Baklib数字化内容管理打破传统束缚提升企业效能
  • 内置序列,专业版已破!
  • 【cran Archive R包的安装方式】
  • 开源先锋DeepSeek-V3 LLM 大语言模型本地调用,打造自己专属 AI 助手
  • 1688平台数据深度挖掘:商品详情与关键词搜索实战指南
  • 在线课堂小程序设计与实现(LW+源码+讲解)
  • linux通过deb包安装(命令模式)
  • 从synchronized到ReentrantLock_Java锁机制的演进与选择
  • waitpid使用
  • 新年祝词(原创)
  • Egg.js GraphQL 完整指南
  • Github 2025-01-28 Python开源项目日报 Top9
  • C语言/C++的函数——memset函数
  • 【2024年华为OD机试】 (C卷,200分)- 发广播(JavaScriptJava PythonC/C++)
  • 【愚公系列】《循序渐进Vue.js 3.x前端开发实践》022-定义组件