1.多线程的基本概念
1.1 简单介绍

进程:进程是程序的的基本执行实体

线程:线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。可以简单理解为是应用软件中相互独立,可以同时运行的功能。

多线程的应用场景:软件中的耗时操作,所有的聊天软件,所有的后台服务器

多线程的作用:提高效率

1.2多线程的两个概念

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

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

1.3多线程的实现方式

1)继承Thread类的方式进行实现

        1>自己定义一个类继承线程类Thread

        2>重写run方法

        3>创建子类对象,并启动线程

2)实现Runnable接口的方式进行实现

        1>自己定义一个类实现Runnable接口

        2>重写run方法

        3>创建自己类的对象

·       4>创建一个Thread类的对象,并开启线程

3)利用Callab接口喝Future接口方式实现

        特点:可以获取到多线程运行的结果

        1>创建一个类实现Callable接口

        2>重写call(有返回值,表示多线程运行的结果)

        3>创建自己类的对象(表示多线程要执行的任务)

        4>创建Future的对象(作用管理多线程的运行结果)

        5>创建Thread类的对象,并启动

1.4常见成员方法

-setName细节:如果没有给线程设置名字,线程也有默认的名字。格式为:Thread-X(X为序号,从0开始)。如果要给线程设置名字,可以用setName方法进行设置,也可以用构造方法设置,但是构造方法需要重写构造方法。

-currentThread细节:获取当前线程的对象。当JVM虚拟机启动之后,会自动的启动多条线程,其中有一条线程就叫做main线程。

-sleep细节:哪条线程执行到这个方法,对应线程就会在这里停留对应的事件,当事件到了会继续执行后面的代码

-优先级Priority的拓展

        线程的调度:抢占式调度(随机的)、非抢占式调度(按顺序执行)

        优先级最小为1,最大为10,优先级越大抢到CPU的概率就越大。线程默认的优先级为5。优先级不是绝对的,只是概率问题。

-setDaemon:守护线程,当其他的非守护线程执行完毕之后,守护线程会陆续结束

1.5线程的生命周期

1.6线程安全问题

1)同步代码块:把操作共享数据的代码锁起来。

格式:synchronized (锁){操作共享数据的代码;}

特点:

1>锁默认打开,有一个线程进去了,锁自动关闭

2>里面的代码全部执行完毕,线程出来,锁自动打开

2)同步方法:就是把synchronize关键字加到方法上

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

特点:

1>同步方法是锁住方法里面所有的代码

2>锁对象不能自己确定--非静态:this   静态:当前类的字节码文件对象

3)Lock锁

死锁--不要让两个锁嵌套起来

1.7生产者喝消费者(等待唤醒机制)

书写多线程代码的套路:

1)写循环  2)同步代码块  3)判断共享数据是否到了末尾(到了末尾)  4)判断共享数据是否到了末尾(没到末尾,执行核心逻辑)

常见方法:

阻塞队列的继承结构

ArrayBlockingQueue,底层是数组,有界。LinkedBlockingQueue底层是链表,无界,但不是真正的无界,最大为int的最大值。

1.8线程池

1)线程池的核心原理

1>创建一个池子,池子是空的

2>提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子,下回再提交任务时,不需要创建新的线程,直接复用已有的线程即可

3>但是如果提交任务时,池子中没有空闲的线程,也无法创建新的线程,任务就会排队等待

2)代码实现步骤

1>创建线程池  2>提交任务  3>所有的任务执行完毕,关闭线程池

Executors:线程池的工具类,通过调用方法返回不同类型的线程池对象

3)自定义线程池

自定义线程池任务拒绝策略

自定义线程池的核心元素

线程池多大合适?

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐