多线程知识点(详解)

谈谈对程序、进程、线程的理解

程序(program):是为了完成特性任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程(process):是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。(如:运行中的QQ,运行中的MP3播放器;程序是静态的,进程是动态的;进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域)。
线程(thread):一个线程是进程的一个顺序执行流。
1)若一个进程同一时间并执行多个线程,就是支持多线程的
2)线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小
3)一个进程中的多个线程共享相同的内存单元/内存地址空间->它们从同一堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源可能就会带来安全的隐患。

进程与线程的区别

一个进程至少有一个线程
线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程的区别在于每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行、必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用来实现进程的调度和管理以及资源分配。

并发原理

多个线程"同时"运行只是我们感官上的一种表现。事实上线程是并发运行的,OS将时间划分为很多时间片段(时间片),尽可能均匀分配给每一个线程,获取时间片段的线程呗CPU运行,而其他线程全部等待。所以微观上是走走停停的,宏观上都在运行。这种现象叫并发。

使用Thread创建并启动线程

Thread类是线程类,其每一个实例表示一个可以并发运行的线程。我们可以通过继承该类并重写run方法来定义一个具体的线程。其中重写run方法的目的是定义该线程要执行的逻辑。启动线程时调用线程的start()方法而非直接调用run()方法。start()方法会将当前线程纳入线程调度,使当前线程可以开始并发运行。当线程获取时间片段后会自动开始执行run方法中的逻辑。

使用Runnable创建并启动线程

实现Runnable接口并重写run方法来定义线程体,然后在创建线程的时候将Runnable的实例传入并启动线程。
这样做的好处在于可以将线程与线程要执行的任务分离开减少耦合,同时java是单继承的,定义一个类实现Runnable接口这样的做法可以更好的去实现其他父类或接口。因为接口是多继承关系

Runnable、Thread创建俩种方式的对比

开发中:优先选择:实现Runnable 接口的方式

原因:
1)实现的方式没类的单继承的局限性
2)实现的方式更适合来处理多个线程共享数据的情况.
联系:public class Thread implements Runnable
相同点:俩种方式都需要重写run(),将线程要执行的逻辑声明在run()方法中。目前俩种方式,要想启动线程,都是调用的Thread类中的start()。

获取线程信息

Thread常用方法:
-start():启动当前线程;调用当前线程的run()
-run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
-currentThread():静态方法,返回执行当前代码的线程
-getName():获取当前线程的名字
-setName();设置当前线程的名字
-yield():该方法用于使当前线程主动让出当次CPU时间片回到Runnable状态,等待分配时间片
-join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后
线程a才结束阻塞状态
-sleep(long millitime):Thread的静态方法sleep用于使当前线程进入阻塞状态:该方法会使当前线程进入阻塞状态指定毫秒,当阻塞指定毫秒后,当前线程会重新进入Runnable状态,等待分配时间片。
-isAlive():判断当前线程是否存活

# Thread提供了获取线程信息的相关方法:
long getId():返回该线程的标识符
-String getName();返回该线程的名称
-int getPriority():返回线程的优先级
-Thread.state getState():获取线程的状态
-boolean isAlive():测试线程是否处于活动状态
-boolean isDaemon();测试线程是否为守护线程
-boolean isInterrupted();测试线程是否已经中断

守护线程

守护线程与普通线程在表现上没有什么区别,我们只需
要通过Thread提供的方法来设定即可:
void setDaemon(boolean )
当参数为true时该线程为守护线程。
守护线程的特点是,当进程中只剩下守护线程时,所有
守护线程强制终止。
GC就是运行在一个守护线程 上的。

线程的优先级:

线程的切换是由线程调度控制的,我们无法通过代码来干涉,
但是我们可以通过提高线程的优先级来最大程度的改善线程获取时间片的几率
线程的优先级被划分为10级,值分别为1-10,其中1最低,10最高。
线程提供了三个常量来表示最低、最高、以及默认优先级:
-Thread.MIN_PRIORITY、
-Thread.MAX_PRIORITY、
-thread.NORM_PRIORITY

getPriority():获取线程的优先级
setPriority():设置线程的优先级

线程的生命周期

JDK中用Thread.State类定义了线程的几种状态
想要实现多线程,必须在主线程中创建新的线程对象。

JAVA语言使用Thread类及其子类的对象来表示线程,
在它的一个完整的生命周期中通常要经历如下五种状态:

新建:当一个Thread类或其 子类的对象被声明并创建时,新生的线程对象处于新建状态。

就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源。

运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能。

阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态。

死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值