• JAVA - 线程


    一、进程

    进程是正在运行的程序

    • 是系统进行资源分配调用独立单位
    • 每一个进程都有它自己的空间系统资源

    二、线程

    线程是进程中的单个顺序控制流,是一条执行路径

    • 单线程:一个进程 如果只有一条执行路径,则称其为单线程
    • 多线程:一个进程如果有多条执行路径,则称其为多线程
    2.1 多线程的实现方式

    方式一:继承 Thread

    • 在类中重写 run() 方法;(run方法是用来封装被线程执行的代码);
    • 启用 start() 方法;(start方法用于启动线程,然后由JVM调用此线程的run方法);

    方法二:实现 Runnable 接口

    • 在类中重写 run() 方法;
    • 创建 Thread 类的对象将实现 Runnable 的类对象作为构造方法内的参数传入;

    相比于继承 Thread 类,实现 Runnable 接口的好处:

    • 避免了 Java 单继承的局限性;
    • 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想;
    2.2 设置和获取线程名称

    Thread类中设置和获取线程名称的方法

    • void setName(String name):将此线程的名称更改为参数 name
    • String getName():返回此线程的名称;
    • 通过构造方法也可以设置线程名称;

    获取 main() 方法所在线程的名称:

    • public static Thread currentThread(): 返回对当前正在执行的线程对象的引用;
    2.3 线程调度

    线程调度有两种调度模型:

    • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片;
    • 抢占式调度模型:优先让优先级高的线程使用 CPU ,如果线程的优先级相同,那么就会随机选择一个(多线程程序的随机性),优先级高的线程获取 CPU 时间片相对多一些;

    JAVA 使用的是抢占式调度模型;

    Thread 类中设置和获取线程优先级的方法

    • public final int getPriority(): 返回该线程的优先级;
    • public final void setPriority(int newPriority): 更改此线程的优先级;
    • 线程的优先级默认值是 5
    • 线程优先级的范围是:1 - 10
    • 线程优先级高仅仅表示线程获取的 CPU 时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到你想要的效果;
    2.4 线程控制
    • static void sleep(long millis): 使当前正在执行的线程停留(暂停执行)指定的毫秒数;
    • void join(): 等待这个线程死亡;
    • void setDaemon(boolean on): 将此标记为守护线程,当运行的线程都是守护线程时,java 虚拟机将退出;
    2.5 线程的生命周期

    线程的生命周期一共分为五个部分分别是:新建就绪运行阻塞以及死亡

    • 新建状态是指新创建一个线程对象;
    • 就绪状态是指一个进程有执行资格但是没有抢到 CPU 的执行权;
    • 运行状态是指有执行资格并抢到执行权;
    • 阻塞状态是指没有执行资格也没有执行权;
    • 死亡状态是指线程结束;(可能是run()方法内执行完毕,也可能是被stop()方法终止运行);

    三、同步代码块

    使多个操作共享数据,可以使用同步代码实现

    • 格式
    synchronized(任意对象){
    	多条操作共享数据的代码;
    }
    
    • 1
    • 2
    • 3
    • synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁;

    同步的好处和弊端

    • 好处:解决了多线程的数据安全问题;
    • 弊端:当线程很多时,因为每一个线程都会去判断同步上的锁,这会耗费很多不必要的时间,无形中降低程序的运行效率;
    3.1 同步方法

    同步方法:把 synchronized 关键字加到方法上

    • 格式:

    修饰符 synchronized 返回值类型方法名(方法参数){ }

    同步方法的锁对象是:this

    同步静态方法:把 synchronized 关键字加到静态方法上

    • 格式

    修饰符 static synchronized 返回值类型方法名(方法参数){ }

    同步静态方法的锁对象是:类名.class

    3.2 线程安全的类

    StringBuffer

    • 线程安全,可变的字符序列
    • 从版本 JDK5 开始,被 StringBuilder 替代,通常应该使用 StringBuilder 类,因为它支持所有相同的操作,但它更快,因为它不执行同步;

    Vector

    • Java2平台v1.2 开始,该类改进了 List 接口,使其成为 Java Collections Framework 的成员,与新的集合实现不同,Vector 被同步,如果不需要线程安全的实现,建议使用 ArrayList 代替 Vector

    Hashtable

    • 该类实现了一个哈希表,它将键映射到值,任何非 null 对象都可以用作键或者值;
    • Java2平台v1.2 开始,该类进行了改进,实现了 Map 接口,使其成为 Java Collections Framework 的成员,与新的集合实现不同, Hashtable 被同步,如果不需要线程安全的实现,建议使用 HashMap 代替 Hashtable
    3.3 Lock锁

    为了更清晰的表达如何加锁和释放锁, JDK5 之后提供了一个新的锁对象 Lock

    Lock 实现提供比使用 synchronized 方法和语句可以获得更广泛的锁定操作;

    Lock 中提供了获得锁和释放锁的方法

    • void lock(): 获得锁;
    • void unlock(): 释放锁;

    Lock 是接口不能直接实例化,Lock 需要使用它的实现类 ReentranLock 来进行实例化;

    3.4线程等待和唤醒方法
    • void wait(): 导致当前线程等待,直到另一个线程调用该对象的 notifynotifyAll 方法;

    • void notify(): 唤醒正在等待对象监视器的单个线程;

    • void notifyAll(): 唤醒正在等待对象监视器的所有线程;

  • 相关阅读:
    Linux yum
    go语言基础学习(一起学习go语言)
    openlayes + vue 最新版本 实现 轨迹移动动画
    Delaunay三角网之逐点插入法(优化版本二)
    iOS-设置指定边圆角(左上、左下等)
    基于单片机的视觉导航小车设计
    leetcode/求平方根
    .NET周报【10月第1期 2022-10-11】
    Unity zSpace开发记录
    高防CDN:构筑网络安全的钢铁长城
  • 原文地址:https://blog.csdn.net/jc15274630894/article/details/127742927