2022-08-02 第四组 蒋萍 线程的简单介绍

线程

更多细节可以转到:
https://www.cnblogs.com/fulfill/p/16543389.html

难!

1、创建线程方式一:继承Thread(不常用)

image

启动线程

必须是Threadstart方法

image

那为什么不直接调run()呢 ??虽然可以执行,但这就是普通的对象调方法,与线程无关;

2、创建线程方式二:实现Runnable接口

源码:

image

  • 实现Runnable接口

image

要启动线程必须要start()

可是实现了Runnable接口,找不到start方法了,怎么办??

想办法

  • 启动线程

借助Thread

image

第二种写法: 使用箭头函数:(lambda表达式)

箭头函数依赖于接口或继承,一定要重写方法,一定要掌握~~~
image

3、创建线程方式三:实现Callable接口

image

它与Runnable

image

jdk1.5出的

image

调用??

Thead类不直接支持Callable

这里需要借助一个工具类 FutureTask(是个泛型类)

image
)

执行的是call()

4、线程的优先级

主方法优先级较高,但线程优先级是概率问题

5、守护线程(Daemon Thread)

知道它是什么即可

Java中提供两种类型的线程

1、用户线程,主线程

2、守护线程(服务于用户线程,需要则出现,不需要就不会运行),对后台支 持任务非常有用(比如垃圾回收线程),大多数jvm线程都是守护线程。

QQ:首页面就是主线程,聊天框就是守护线程
image

6、线程的生命周期(重要)

面试爱考

NEW

还没调用start()

RUNNABLE ,就绪

线程正在JVM中被执行,等待来自操作系统的调度

BLOCKED,阻塞

因为某些原因不能立即执行,需要挂起。外部原因

WAITING,无限期等待

如果没被唤醒,那就一直等待

TIMED_WAITING,有限期等等

等待一个指定时间

TERMINGATED,终止线程状态

程序已经执行完毕

  • 阻塞和等待

阻塞是因为外部原因需要等待

等待一般是主动调用方法,发起主动等待,等待可传参确定等待时间

image

7、一些方法

sleep()

Thread类的静态方法,用于暂停当前线程活动

image

join()

本意是阻塞主线程,但插队也是有概率的

其他

1、CPU多核缓存结构

物理内存:硬盘内存,推荐固态硬盘,尽量不要选择混合硬盘

CPU缓存是为了提高程序运行的性能,CPU处理速度最快,内存次之,硬盘最慢;

线程安全问题

  • 指令重排:简单来说,就是指在程序中写的代码,在执行时并不一定按照写的顺序,“不懂规矩 ”,

    • 避免: volatile关键字:禁止重排;Volatile通过内存屏障可以禁止指令重排序,内存屏障是一个CPU的指令,它可以保证特定操作的执行顺序
  • 线程的可见性

    • 线程间互相独立,不知道外面已经把数据改了,”关我屁事“

    • 怎么解决?volatile: 强制改变变量的读写直接在内存中操作,可以保证变量写入时对其他线程的可见。

  • 线程争抢

    • 解决线程争抢问题最好的办法:【加锁】

synchronized

线程安全的实现方法

(1)数据不可变:一切不可变的对象一定是线程安全的,

对象的方法的实现方法的调用者,不需要再进行任何线程安全的保障措施;

比如final关键字修饰的基本数据类型,String、

只要一个不可变的对象被正确创建出来,那外部的可见状态永远都不会改变

(2)互斥同步,加锁,【悲观锁】-----简单好用,用的多

(3)非阻塞同步,比较耗资源,【无锁编程】,自旋,cas实现

(4)无同步方案,多个线程需要共享数据,但这些数据又可以单独的线程中计算,得出结果

我们可以把共享数据的可见范围限制在一个线程之内,就无需同步,把共享数据拿过来,各用各的,从而保证线程安全。ThreadLocal(了解即可)

要掌握的:

线程创建,

线程安全实现方法

posted @ 2022-08-02 18:15  来日可追  阅读(28)  评论(0编辑  收藏  举报