2022-8-2第一组孙乃宇 多线程
进程和线程
什么是进程
-
我们电脑中的每一个正在运行的程序都是一个进程,程序运行时系统就会创建一个进程,并为它分配资源。
-
线程:线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,比如qq可以开多个窗口,和多个人聊天,每个窗口就是一个线程。
进程和线程的关系
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
java中创建线程
继承Thread类
在java中,创建线程有3种方式。
1.继承Thread类,并且重写run方法,Thread类中的方法不是抽象方法,Thread类也不是抽象类
MyThread类继承了Thread之后,他就是一个线程类。要让线程启动。调用线程的start方法。
class MyThread extends Thread{
2.实现Runnable接口
创建类实现Runnable接口,重写run()方法
class MyThread2 implements Runnable{
实现Callable接口
创建类实现Callable接口,重写call()方法
class MyThread03 implements Callable<String>{
守护线程
守护线程 java中提供两种类型的线程 1.用户线程 2.守护程序线程
守护线程为用户线程提供服务,仅在用户线程运行时才需要。
守护线程对于后台支持任务非常有用。 垃圾回收,大多是jvm线程其实都是守护线程。
public class Ch05 extends Thread{
public static void main(String[] args) {
Ch05 ch05=new Ch05();
ch05.setDaemon(true);//设置为true则为守护线程
}
}
生命周期
NEW:这个状态主要是线程未被start()调用执行
RUNNABLE:线程正在JVM中被执行,等待来自操作系统的调度
BLOCKED:阻塞,因为某些原因不能立即执行,需要挂起等待。
WAITING:无限期等待。Object。如果没有唤醒,则一直等待。
TIME_WAITING:有限期等待,线程等待一个指定的时间
TERMINATED:终止线程的状态,线程已经执行完毕。
等待和阻塞这两个概念有点像,阻塞因为外部原因,需要等待 等待一般是主动调用方法,发起主动的等待,等待还可以传入参数,来确定等待时间。
CPU多核缓存结构
CPU缓存为了提高程序运行的性能,现在CPU在很多方面对程序进行优化
CPU处理速度最快,内存次之,硬盘速度最低。
在CPU处理内存数据的时,如果内存运行速度太慢,就会拖累cpu的速度,为了解决这样的问题,CPU设计了多级的缓存策略。
CPU分为三级缓存:每个CPU都有L1,L2缓存,但是L3缓存是多级公用的。
CPU查找数据时,CPU->L1->L2->L3
从CPU到内存,60~80纳秒
从CPU到L3,15纳秒
从CPU到L2,3纳秒
从CPU到L1,1纳秒
寄存器,0.3纳秒
进一步优化,CPU每次读取一个数据,读取的是与它相邻的64个字节的数据 【缓存行】
英特尔提出了一个MESI协议
1.修改态,此缓存被动过,内容与主内存中不同,为此缓存专有
2.专有态,此缓存与主内存一致,但是其他CPU中没有
3.共享态,此缓存与主内存一致,其他的缓存也有
4.无效态,此缓存无效,需要从主内存中重新读取
线程安全的实现方法
线程安全的实现方法
1.保证数据不可变
一切不可变的对象一定时线程安全的
对象方法的事项方法的调用者,不需要在进行任何的线程安全的保障的措施
比如说final关键字修饰的基本数据类型,字符串
只要一个不可变的对象它能够正确的创建出来,外部的可见状态永远都不会改变
2.互斥同步,加锁。【悲观锁】
3.非阻塞同步【无锁编程】,自旋,我们会用cas来实现这种非阻塞状态
4.无同步方案:多个线程共享数据,这些数据又可以在单独的线程中计算的出结果,我们能可以把共享数据的可见 范围限制在一个线程之内,这样就无需同步了,把共享的数据拿出来,我用我的,你用你的,从而保证线程的安全 ThreadLocal
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】