2022-08-02 第三小组 孙翰章 学习笔记

JAVA15


1.创建线程

在Java中,创建线程有3种方式。

(1)继承Thread类,并且重写run方法

        Thread类中的run方法不是抽象方法,Thread类也不是抽象类。

        MyThread当继承了Thread类之后,它就是一个独立的线程。

        要让线程启动。调用线程的start方法。

        当调用start方法启动一个线程时,会执行重写的run方法的代码。

        调用的是start,执行的是run,为什么不直接调run?--> myThread.run(); //是普通的对象调方法,与咱们线程什么的无关。

线程的优先级:>>>主方法的优先级高。

注意~~线程的优先级是概率问题!做不到100%

90%的可能会先跑主方法,10%的可能先跑myThread

主方法是一个独立的线程,调用启动开启另一个独立线程,它俩就是并行的两个线程。

(2)实现Runnable接口

        - >使用箭头函数(lambda表达式λ)

        箭头函数依赖于接口/抽象类,重写方法。小括号代表重写里面的无参方法

        线程的休眠..线程中止异常

        Java的单继承多实现现状,注意优先考虑实现Runnable接口(-->函数式接口,考虑使用箭头函数)。

        如果想让线程启动,必须调用Thread中的start方法。

        问题:实现Runnable接口后,找不到start方法了

(3)实现Callable接口


2.守护线程

        Java种提供两种类型的线程:用户线程、守护程序线程。

        守护线程为用户线程提供服务,仅在用户线程运行时才需要。

        守护线程对于后台支持任务非常有用。

        垃圾回收:大多数JVM线程都是守护线程。

        QQ:主程序就是用户线程。

        创建守护线程:任何线程继承创建它的线程守护进程状态的时候,由于主线程是用户线程,因此在main方法内启动的任何线程默认都是守护线程。(用Java操作线程基本上操作的都是守护线程。)

        线程的生命周期:从摇篮到坟墓。

                NEW:这个状态主要是线程未被start()调用执行

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

                BLOCKED:阻塞,因为某些原因不能立即执行,需要挂起等待。

                WAITING:无限期等待。Object类,如果没有唤醒,则一直等待。

                TIMED_WAITING:有限期等待,线程等待一个指定的时间。

                TERMINATED:终止线程的状态,线程已经执行完毕。

        等待和阻塞两个概念有点像,阻塞因为外部原因,需要等待。而等待一般是主动调用方法,发起主动的等待,等待还可以传入参数确定等待的时间。

sleep休眠

join插队


3.线程安全

        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纳秒

从CPU到寄存器,0.3纳秒

        进一步优化,CPU每次读取一个数据,读取的是与它相邻的64个字节的数据。缓存行两个CPU读取同一个数据..高并发

英特尔提出一个协议MESI协议
1.修改态,此缓存被动过,内容与主内存中不同,为此缓存专有
2.专有态,此缓存与主内存一致,但是其他CPU中没有
3.共享态,此缓存与主内存一致,其他的缓存也有
4.无效态,此缓存无效,需要从主内存中重新读取

        线程之间的可见性

        thread线程一直在高速读取缓存中的isOver,不能感知主线程已经把isOver修改了。

这就是线程可见性的问题。

        怎么解决?--volatile能够强制改变变量的读写直接在内存中操作

        线程争抢     解决线程争抢的问题,最好的办法就是加锁。synchronized同步锁,线程同步。

        当一个方法加上了synchronized修饰,这个方法就叫做同步方法。

        线程安全的实现方法

                a:数据不可变。

                一切不可变的对象一定是线程安全的。

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

                比如final关键字修饰的基本数据类型,字符串。

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

                b:互斥同步。加锁.. 悲观锁

                c:非阻塞同步。无锁编程,自旋。我们会用cas来实现这种非阻塞同步。

                d:无同步方案。多个线程需要共享数据,但是这些数据又可以在单独的线程中计算,而得出结果。

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


所学知识不能完全掌握 可以理解

天气雨 心情尚佳

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值