多线程之Thread类的基本用法


一、进程和线程

进程:程序在系统中的一次执行过程

进程是现代操作系统中资源分配(CPU,内存等关键系统资源)的最小单位
不同进程之间资源是相互独立的

线程就是进程中的一个独立子任务

同一个进程的所有线程共享进程的资源,线程是操作系统任务执行的基本单位

进程和线程的区别:
1.进程是os资源分配的基本单位,线程是os系统调度的基本单位
2.创建和销毁进程的开销要远比创建和销毁线程大得多,线程更加轻量化。
3.调度一个线程也远比调度一个进程快得多
4.进程包含线程,每个进程至少包含一个线程(主线程)
5.进程之间彼此相对独立,不同的进程不会共享内存空间,同一个进程共享内存空间。

JDK提供的线程库实际上就是利用操作系统提供的线程库进行二次封装

进程:操作系统资源分配(CPU和内存)的基本单位,不同进程之间相互隔离的,内存空间独立,不共享
线程:os任务调度的基本单位,线程存在于进程之内,每个进程至少都存在一个线程(主线程,其它的子线程和主线程共享进程的资源)

二、Thread类的基本使用

先回顾以下之前的代码,入口都是main(主线程),所有的调用都是从主方法开始的,所有的任务都在主方法中(主线程)进行
Java中描述线程这个对象的类 - java.lang.Thread类线程的核心类,都是通过Thread类来启动一个新的线程。
在这里插入图片描述
在这里插入图片描述
若这四个线程是顺序执行的,
主方法会不会打印输出?肯定不会,要等三个线程的run方法都执行完才会走到打印
其它线程的打印呢?只有m1线程的run方法会打印

JDK和JRE相比最大的区别就是JDK提供了很多开发程序会用到的辅助工具 jconsole命令 :查看当前运行的JVM内部的线程情况
在这里插入图片描述

1.创建线程

创建线程:Java中创建一个线程一共有四种方法

a.继承Thread类,覆写run方法(线程的核心工作任务方法)
b.覆写Runnable接口,覆写run方法
(a和b最终启动线程都是通过Thread类的start启动线程)
c.覆写Callable接口,覆写call方法
d.使用线程池创建线程

a方式下线程的创建与启动:
1.一个子类继承Thread类
2.覆写run方法
3.产生当前类的子对象,而后调用start方法
在这里插入图片描述
在这里插入图片描述
注意:
调用start方法启动线程,是由JVM产生操作系统的线程并启动,到底啥时候真正启动,对于我们来说不可见,也没法控制。
在这里插入图片描述
b.实现Runnable接口,覆写run方法
第三步还是需要创建Thread对象,调用start方法
在这里插入图片描述
在这里插入图片描述

推荐使用方式2,实现Runnable接口更加灵活,子类还能实现别的接口,继承别的类
方式1的话,只能继承Thread,单继承局限

关于方式a和方式b的不同写法
1.使用匿名内部类创建Thread
在这里插入图片描述
2.使用匿名内部类实现Runnable接口
在这里插入图片描述
3.使用Lambda表达式实现Runnable接口:
在这里插入图片描述
多线程和顺序执行的执行速度差异:
执行10个亿这么大数字的连续累加
顺序执行,先+10亿,再+10亿,最终都是在主线程中+20亿
并发执行,子线程+10亿,主线程+10亿,主线程和子线程并发的在执行+10亿理论来讲,并发执行的速度是顺序执行的一倍,耗时是一半~
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多线程最大的应用场景就是把一个大任务拆分为多个子任务(交给子线程),多个子线程并发执行,提高系统的处理效率~~
12306系统多线程程序
我们每个人其实都是一个线程,我们多个人可以同时登录系统买票,付款操作是一个非常耗时的操作
若不是多线程,每个人买票都得排队,从第一个登录系统的人开始买票,依次进行,非常慢,这个程序就没法用。

2.Thread类常见方法

无论是继承Thread类还是实现Runnable接口,最终启动线程调用的都是Thread类的start方法
Thread类就是JVM描述管理线程的类,每个线程都对应唯一的一个Thread对象

2.1.构造方法

在这里插入图片描述
在这里插入图片描述

2.2.Thread类的核心属性

在这里插入图片描述

1、ID是线程的唯一标识,不同线程不会重复
2、名称是各种调试工具用到
3、状态表示线程当前所处的一个情况
4、优先级越高的线程越有可能被CPU优先执行,咱们Java程序只是建议优先级高的线程优先执行,到底执行不执行,OS说了算。
5、关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。
6、是否存活,即简单的理解,为run方法是否运行结束了
7、线程的中断问题,下面我们进一步说明

在这里插入图片描述
在这里插入图片描述

2.3.启动线程调用的是Thread类的start方法

注意:
Thread类中run和start的区别:

run方法是线程类的工作任务——run方法决定了线程启动之后要干的事情,当run方法执行完毕(run是由JVM来执行的),线程就进入销毁状态。
start方法是Thread类中启动线程的方法,只有当线程对象调用start方法之后才会被系统调度,进入运行状态。

2.4.中断线程 => 线程间通信

中断一个正在执行的线程(run方法还没有执行结束),普通线程会在run方法执行结束之后自动停止

中断线程有两种方式:
a.通过共享变量进行中断
Thread类的所有静态方法都是在哪个线程中调用的,就生效在哪个线程。
在这里插入图片描述
b.使用Thread.interrupted() 静态方法 或 Thread对象的成员方法isInterrupted

Thread类的内部包含了一个属性,当前线程是否被中断属性
在这里插入图片描述
在这里插入图片描述
线程收到内置的中断通知有两种方式

a.当线程调用sleep/wait/join等方法处在阻塞状态时,收到中断通知Thread.interrupt()
就会抛出一个中断异常InterruptedException
当抛出异常后,当前线程的中断状态就会被清除

b.线程没有调用以上三种方法时,处在正常运行状态,收到中断通知thread.interrupt()

Thread.interrupted():判断当前线程是否被中断,若中断状态为true,清除中断标志
在这里插入图片描述
Thread.currentThread.isInterrupted():判断指定线程对象是否为中断状态,若状态为true,不会清除中断标志
在这里插入图片描述
Java中线程的启动和终止,中断,Java程序员说了不算,都是系统调度的
我们所谓的中断线程只是更改线程的状态而已,要想让线程终止,run方法执行结束,自然就终止了,中断线程其实是线程间通信的一种方式。
a.使用外部的共享变量

在这里插入图片描述

2.5.等待一个线程

线程对象.join():
在哪个线程中调用别的对象的join方法,意思就是这个线程要等待另一个线程执行完毕再继续执行本线程的后序代码。
eg:主线程中调用thread1.join(),主线程就会进入阻塞状态,直到thread1执行结束,主线程才会继续向后执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.6.获取当前正在执行的线程对象:

Thread.currentThread() => 获取正在执行的线程对象

2.7.休眠当前线程

Thread.sleep(long millis):在哪调用,就休眠哪个线程
在这里插入图片描述

3.线程的状态

在这里插入图片描述

1、NEW:安排了工作,还未开始行动
2、RUNNABLE:可工作的.又可以分成正在工作中和即将开始工作.
3、BLOCKED:这几个都表示排队等着其他事情
4、 WAITING:这几个都表示排队等着其他事情
5、TIMED_WAITING:这几个都表示排队等着其他事情.
6、TERMINATED:工作完成了.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
线程的阻塞状态(该线程需要暂缓执行,这三个造成的暂缓执行的原因不同)
WAITING:无条件等待,当线程调用wait()/join()/LockSupport.park()不加超时时间的方法之后所处的状态,如果没有被唤醒或等待的线程没有结束,那么将一直等待,当前状态的线程不会被分配CPU资源和持有锁。
在这里插入图片描述
TIMED_WAITING:有条件的等待,当线程调用sleep(睡眠时间)/wait(等待时间)/join(等待时间)/ LockSupport.parkNanos(等待时间)/LockSupport.parkUntil(等待时间)方法之后所处的状态,在指定的时间没有被唤醒或者等待线程没有结束,会被系统自动唤醒,正常退出。

BLOCKED:锁等待,需要等待其它线程释放锁对象
等待监视锁,这个时候线程被操作系统挂起。当进入synchronized块/方法或者在调用wait()被唤醒/超时之后重新进入synchronized块/方法,锁被其它线程占有,这个时候被操作系统挂起,状态为阻塞状态。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Thread.yield( )方法:
使当前线程从RUNNABLE(运行状态)变为READY(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。

到底啥时候让出CPU,又是啥时候被CPU再次调度,都是os调度的,我们无权选择,有可能让出之后立马被调度了,也有可能让出之后很久都不调度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值