《张三记录-java》线程

线程

一.简介

1.进程

​ 程序:程序就是为了完成特定任务,用某种语言编写的一组指令的集合,就是一段静态的代码

​ 进程:在操作系统中独立运行的程序,每运行一个应用程序就对应一个进程 process

​ 就是一个正在运行的exe文件,进程是动态的,有启动到运行 到结束的一个过程

2.线程

线程: 是进程内部的一个执行单元,用来执行应用程序中的一个功能

多线程:在一个应用程序中可以同时执行多个功能,每一个功能就对应一个线程 迅雷中 同时执行多个下载任务,就是多个线程在运行

特性:

  • 一个进程中可以有多个线程
  • 一个进程中的多个线程共享进程中的资源

3.CPU时间片

对于单核CPU,某个时间点只能处理一件事情

CPU为 各个程序分配时间,称为时间片,该进程运行的时间(时间很短)

  • 从表面看每个程序同时运行的,实际上CPU在同一个时间点只能执行一个程序
  • 只是CPU在很短的时间内,在不同程序之间进行切换,轮流执行每个程序,执行的速度很快,感觉上在同时执行

二.线程的创建

实际上,java程序在运行是至少有两个线程,主线程,垃圾回收线程(gc)

  • 主线程: JVM启动时会创建一个主线程,用来执行main()方法中的代码
  • 垃圾回收线程: 低级别的线程,用来回收垃圾变量
  • 如果需要实现多个线程,可以创建新的线程(自定义线程)

两种方式:

  • 继承Thread类
  • 实现Runable接口

1.继承Thread类

  • 定义一个类,继承Thread类,Thread类是线程的父类,提供了一些操作线程的方法
  • 重写父类中run()方法
  • 创建该类的实例,创建线程对象
  • 启动线程,线程对象调用start()方法。不能调用run()方法。start()被调用不是指线程一定能运行,还的看是否能够抢到CPU

2.实现Runable接口

  • 定义一个类,继承Thread类,Thread类是线程的父类,提供了一些操作线程的方法
  • 重写父类中run()方法
  • 创建该类的实例,创建线程对象
  • 创建Thread类,将自己的线程类对象传入
  • 启动线程,线程对象调用start()方法。不能调用run()方法

3.两种方式的对比

继承Thread

  • java单一继承,无法继承其他类

实现Runable接口

  • 可以继承其他类,避免了单一继承的局限性
  • 适合多个相同程序代码的线程去处理同一个资源(共享一个资源)

4.线程的生命周期

1.线程的多种状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tHkrmTY-1610940016669)(img/线程的生命周期.png)]

2.方法

方法含义
start()启动线程,就入就绪状态
sleep()休眠线程,线程从运行状态 进入 阻塞状态 静态方法
join()暂停线程的执行,等待另一个线程加入进来,执行完成。从运行状态进入阻塞状态
yield()暂停线程(让出CPU资源), 线程从运行状态进入就绪状态,只是一瞬间的事,其他线程不一定能够执行。 静态方法
interrupt中断线程的休眠状态,如果一个线程的休眠被中断,会报错

三.线程的安全性问题

1.线程安全问题

多个线程同时访问共享数据可能会出现问题,称为线程安全问题 ---- 异步线程

当多个线程同时访问共享数据,由于cpu切换,导致一个线程只执行了一部分代码,没有执行完成,此时另一个线程参与进来,导致共享数据发生异常

2.同步线程 和异常线程

  • 同步线程:在多个线程同时执行时,一个线程要等待上一个线程执行完成后,才开始执行。 ----- 排队
  • 异步线程:在对个线程同时执行时,不用等待上面的线程是否结束,一起执行。

3.解决安全问题

线程的同步机制(异步线程— 同步线程)

synchronized +锁

  • 同步方法 ---- synchronized 修饰方法

  • 同步代码块— synchronized 修饰代码块

    synchronized ( 对象锁-对象名){

    ​ //同步的代码

    }

锁:也称为对象锁,每个对象都自带一个锁(标识),不同对象的锁不一样

执行过程:

  • 当线程执行同步方法或者同步代码块时,必须获取特定对象的锁,才能执行
  • 一旦一个对象的锁被获取了,则该对象不再拥有锁,直到线程执行完代码,才会释放锁
  • 如果线程无法获取特定对象的锁,则线程会进入对象的锁池中等待,直到锁被归还,此时需要锁的线程可以去竞争锁。

四.线程的通信

1.锁池和等待池

每个对象都有锁池和等待池

锁池:

  • 当线程无法获取对象锁,此时进入锁池中
  • 如果对象锁被归还,锁池中的多个线程竞争锁

等待池:

  • 当线程获取锁后,可以调用wait()方法,放弃锁,进入等待池
  • 当其他线程调用对象的notify notifyAll方法时,等待池中的线程被唤醒,进入锁池
  • 在锁池中可以继续竞争锁

2.方法

方法含义
wait()放弃对象锁
notify()随机唤醒一个等待池中的线程
notifyAll()唤醒等待池中的所有线程

注意:

  • 这三个方法 只能在synchronized块中使用,只有获取了锁的线程才能调用
  • 等待和唤醒必须使用同一个对象

3.线程通信的案列

模拟生产者和消费者的问题

生产者线程:

  • 生产商品,放入仓库
  • 当仓库满了,停止生产

消费者线程:

  • 消费商品,从仓库中取出
  • 当仓库为空时,停止消费

五.线程单例

1.简介

同一个线程中获取的是同一个对象,不同线程中获取不同对象

java中提供了一个ThreadLocal类,直接为实现了线程单例

用来管理对象,在同一个线程中多次获取对象,都是同一个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值