java---多线程

本文深入探讨了Java中的进程与线程,包括它们的区别、线程的组成与特点,以及如何创建和管理线程。讨论了线程状态、常用方法如休眠、加入和优先级设置,还涉及线程同步的重要性,通过同步代码块和同步方法防止数据不一致。此外,文章提到了线程安全问题,如死锁,以及线程通信的wait和notify方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1.什么是进程

在这里插入图片描述

2.什么是线程

在这里插入图片描述

3.进程和线程的区别

  • 1.进程是操作系统资源分配的基本单位,而线程是cpu的基本调度单位
  • 2.一个程序运行后至少有一个进程
  • 3.一个进程可以包含多个线程,但是至少需要一个线程,否则这个进程是没有意义的。
  • 4.进程间不能共享数据段地址,但同进程的线程之间可以。

4.线程的组成

  • 任何一个线程都具有基本的组成部分:
    • CPU时间片:操作系统(os)会为每个线程分配执行时间。
    • 运行数据
      • 堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象。
      • 栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈。
    • 线程的逻辑代码

5.线程的特点

  • 1.线程抢占式执行
    • 效率高
    • 可防止单一线程长时间独占cpu
  • 2.在单核cpu中,宏观上同时执行,微观上顺序执行。

6.创建线程

  • 创建线程的三种方式
  • 1.【继承Thread类,重写run方法】
  • 2.【实现Runnable接口】
  • 3.实现Callable接口

在这里插入图片描述
注意:启动线程,不能调用run方法,不然就是一个普通方法的调用,而不是启动线程。

7.获取和修改线程名称

  • 获取线程ID和线程名称
    • 1.在Thread的子类中调用this.getId()或this.getName();
    • 2.使用Thread.currentThread().getId()和Thread.currentThread().getName();
  • 修改线程名称
    • 1.调用线程对象的setName()方法
    • 2.使用线程子类的构造方法赋值。
      在这里插入图片描述
      注意:创建MyRunnable对象,表示线程要执行的功能。而是一个线程。

8.线程的状态(基本)

在这里插入图片描述

9.常见方法

  • 休眠
    • public static void sleep(long millis)
    • 当前线程主动休眠mollis毫秒。
  • 放弃
    • public static void yield()
    • 当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片。
  • 加入:
    • public final void join()
    • 允许其他线程加入到当前线程中。

注意:加入当前线程(main),并堵塞当前线程,直到加入线程执行完毕

  • 优先级
    • 线程对象.setPriority()
    • 线程优先级为1-10,默认为5,优先级越高,表示获取cpu机会越多。
  • 守护线程
    -线程对象.setDaemon(true);设置为守护线程
    • 线程有两类:用户线程(前台线程),守护线程(后台线程)
    • 如果程序中所有前台线程都执行完毕了,后台线程会自动结束。
    • 垃圾回收器线程属于守护线程。

10.线程的状态(等待)

在这里插入图片描述

11.线程的安全问题

在这里插入图片描述

  • 多线程安全问题
    • 当多线程并发访问临界资源时,如果破坏原子操作,可能会造成数据不一致。
    • 临界资源:共享资源(同一对象),一次仅允许一个线程使用,才可保证其正确性。
    • 原子操作:不可分割的多步操作,被视作一个整体,其顺序和步骤不可打乱或缺省。

12.同步方式(1)

  • 同步代码块:
    synchronized(临界资源对象){//对临界资源对象加锁
    //代码(原子操作)
    }
    注:每个对象都有一个互斥锁标记,用来分配给线程的。
    只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块
    线程退出同步代码块时,会释放相应的互斥锁标记。

13.线程的状态(阻塞)

在这里插入图片描述

14.同步方式(2)

  • 同步方法:
    synchronized 返回值类型 方法名称(形参列表0){//对当前对象(this) 加锁
    //代码(原子操作)
    }
    注意:如果是普通方法,锁是当前对象,如果是静态方法,锁是当前类。

注:只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块
线程退出同步代码块时,会释放相应的互斥锁标记。

15.同步规则

  • 注意:
    • 只有在调用包含同步代码块的方法,或者同步方法时,才需要对象的锁标记。
    • 如果用不包括同步代码块的方法,或普通方法时,则不需要锁标记,可直接调用。
  • 已知JDK中线程安全的类:
    • StringBuffer
    • Vector
    • Hashtable
    • 以上类中的公开方法,均为synchonized修饰的同步方法。

16.经典问题

  • 死锁
    • 当第一个线程拥有A对象锁标记,并等待B对象锁标记,同时第二个线程拥有B对象锁标记,并等待A对象锁标记时,产生死锁。
    • 一个线程可以同时拥有多个对象的锁标记,当线程阻塞时,不会释放已经拥有的锁标记,由此可能造成死锁。

17. 线程通信

  • 等待:
    • public final void wait()
    • public final void wait(long timeout)
    • 必须在对obj加锁的同步代码块中,在一个线程中,调用obj.wait()时,此线程会释放其拥有的所有锁标记。同时此线程阻塞在o的等待队列中。释放锁,进入等待队列。
  • 通知:
    • public fianl void notify()
    • public final void notifyAll()
      可能存在的问题如下:
      在这里插入图片描述在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

(YSY_YSY)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值