多线程概述

一、多线程

(一)程序和进程

1.程序:一个固定的存储有逻辑和数据的集合,是一个静态的状态,存储在磁盘上

2.进程:一个正在运行着的程序,是一个动态的概念,一般运行在计算机内存中

3.查看计算机进程的快捷键:ctrl+shift+esc

(二)进程和线程

1.进程:是一个正在运行的程序,会分配一部分系统资源,是一个独立的资源分配单位

2.线程:一个正在独立执行的路径,多线程,在执行某个程序的时候,该程序与多个子任务,每个

线程都可以独立的完成其中一个子任务,在子任务之间,没有什么依赖,可以独立执行

3.进程和线程的关系

(1)进程适用于分配系统资源的单位

(2)一个进程中,可以有多个线程,但是一个进程中,至少有一条线程

(3)线程不会独立分配资源,一个进程中的所有线程,共享的是同一个进程的资源

(三)并行和并发

1.并行:在一个时间点,有多个任务(进程、线程)正在执行,多核心、多CPU编程

2.并发:在一个时间点,有多个任务同时发起,但是,在一个时间点,同时只能有一个任务正在运

行,单核心、单CPU编程

(四)Q&A

CPU在多个任务之间来回切换,效率是提高了还是降低了

1.对于一个任务来说,肯定是降低了

2.对于整个计算机来说,效率是提高了,计算机硬件的运行效率是不同的

二、多线程的实现方式

(一)第一种:继承方式

1.在JDK中有一个类是线程类:Thread

2.操作步骤:

(1)自定义一个类型继承Thread类

(2)在自定义类型中重写Thread类中的run方法,方法体就是将来线程的任务

(3)创建自定义类型对象,表示一条线程

(4)调用start()方法,启动线程

(二)第二种:实现方式

1.在JDK中有一个接口:Runnable

2.步骤

(1)自定义一个类,实现Runnable接口

(2)在自定义类中重写Runnable接口中的run方法

(3)创建自定义类型对象,表示一个任务

(4)创建线程对象,将任务添加到线程中

(5)线程对象调用start()方法,启动线程

(三)匿名内部类简化多线程

1.继承方式

2.实现方式

(四)两种方式的比较

1.代码复杂程序

(1)继承的方式比较简单

(2)实现的方式相对复杂

2.实现原理

(1)继承:创建好线程对象后,调用start()方法启动线程,start()方法又调用start0()方

法,start0()方法在后续调用run()方法,因为在自定义类型中重写了Thread的run()方法,

所以直接执行重写后的run()方法,我们重写时定义的业务逻辑就执行了

(2)实现:创建接口的实现类对象,这个对象是一个任务对象,创建线程对象,将任务对象封装

到线程对象中,将任务对象当作参数进行传递给线程对象,线程对象在创建的过程中,连续调用了

两个init方法,之后,将任务对象作为线程的成员变量,赋值给线程。创建好线程之后,调用start

方法启动线程,start方法又调用了start0方法,start0方法继续调用线程中run方法,因为在初始化

时,已经将任务对象封装进线程对象中,所以此时是线程对象在调用线程类中的run方法,此时的

run方法就需要执行,判断任务对象是否为null之后,任务对象调用接口中的run方法,因为接口中

的run方法已经被实现了,所以根据任务对象所属类型,调用任务对象所属类中重写过的run方法,

执行重写之后的逻辑

3.设计

(1)继承:自定义类型继承了Thread类之后就无法在继续继承其他类型,代码扩展性较差

(2)实现:一个类,实现多个接口的同时还可以在继承一个类,扩展性较强

4.灵活性

(1)继承:将业务逻辑和线程对象绑定在了一起,耦合度高,灵活性差

(2)实现:将任务对象和线程对象分割开,降低耦合度,灵活性提高,一个任务对象可以被多个

线程执行,一个线程也可以执行不同的任务对象,并且将来可以将任务对象,提交到线程池中,任

务对象被不同的线程执行,也方便多线程之间的数据交互

三、Thread中的常用方法

(一)获取线程的名称

1.getName():获取线程名称

2.注意

(1)如果没有给线程起名字,线程具有默认的名字格式为Thread-x,x从0开始依次递增

(2)继承的方式中,可以直接在run方法中调用getName()方法,是因为继承方式的run和

getName()方法都来源于Thread类

在实现方式中,run方法不能直接调用getName()方法,因为run方法是Runnable接口的实现类

对象实现了的抽象方法,与Thread没有什么关系

(二)设置线程名称

1.setName(String name):设置线程名称

2.构造方法赋值

(1)Thread(String name)

(2)Thread(Runnable target,String name)

(三)获取当前线程对象

1.方法:currentThread()

(1)返回当前正在执行的这段代码所在线程的线程对象

(2)那条线程执行这个方法,获取的就是那条线程的对象

2.作用:某段代码只要是在执行,就一定会在某个线程中,此时如果调用该方法,该段代码在哪条

线程执行,就返回哪个线程的对象

(四)线程休眠

1.sleep(long millis):让当前线程休眠指定毫秒值

2.作用:当某个线程执行到该方法时,就让执行该方法的线程休眠指定毫秒值

3.注意

(1)当在重写的方法中使用该方法时,如果重写前的方法没有声明异常,重写后的方法只能

try...catch

(2)该方法会出现InterruptedException,中断异常,当线程在休眠的过程中被打断,会报此异常

(五)守护线程

1.概述:保证其他非守护线程能够正常执行的线程,为其他非守护线程提供良好的运行环境,守护

线程死亡,非守护线程正常执行,非守护线程死亡,守护线程存在的意义也就不大了,片刻之后也

会消亡

2.isDaemon():判断一个线程是不是守护线程

3.setDaemon(boolean on):将一个线程设置为守护线程

4.任何一个线程被创建出来之后,都是一个非守护线程

(六)线程的优先级

1.执行多线程的时候,每个线程都有优先级,优先级高的先执行,在整个执行周期内比较靠前执行

2.有三个线程优先级的常量

(1)MAX_PRIORITY:10

(2)MIN_PRIORITY:1

(3)NORM_PRIORITY:5

3.setPriority(int newPriority):设定线程的优先级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值