深入Java并发编程(一):多线程基础

前言

本文主要讲述线程实现、线程状态、线程优先级、守护线程、线程常用API以及线程中断和停止。

一、线程实现

1、继承Thread类,继承后重写run方法,调用start()方法就可以跑起来了

2、实现Runnable接口,实现后一定要重写run方法,然后传参给Thread类的构造函数创建出Thread对象,然后调用start(0方法

3、实现Callable接口,与Runnable相比,执行完run方法后有返回值,其它一致

 

二、线程状态

线程共有5种状态:

1、创建状态:我们创建出一个线程对象后,它就进入了创建状态

2、运行状态:我们调用了start()方法后,线程进入了运行状态,此时它可能正在运行,也可能正等待CPU分配时间片

3、等待状态:此时线程在等待其他线程的唤醒或是等待一定时间后由系统唤醒,这又可以分为:

                         无限等待状态:线程不会被CPU分配时间片直到其他线程的唤醒,常见用例:

                                                  未设置Timeout参数的Object.wait()

                                                  未设置Timeout参数的Thread.join()

                         限期等待状态:线程会在一定时间后被系统自动唤醒,常见用例:

                                                   设置了Timeout参数的Object.wait()

                                                   设置了Timeout参数的Thread.join()

                                                    Thread.sleep()方法

4、阻塞状态:此时线程正在等待获取一个排他锁。

5、结束状态:线程执行完run方法后进入结束状态

 

三、线程优先级

Java线程的优先级共有10种,默认优先级为5,最大为10,最小为1。线程的优先级并不意味着一定能先得到CPU的时间片分配,只是让其更容易被系统选择分配。值得我们注意的是,java线程是通过映射到系统的原生线程上实现的,所以线程调度最终还是取决于操作系统,比如windows线程优先级只有7种,因此java的几个不同优先级映射到windows中就会出现相同的情况。

四、守护线程

守护线程也被称为后台线程,如要设置必须在创建状态也就是start前设置,守护线程是可以继承的,如果当前所有的用户线程都退出了,那么守护线程也会退出。守护线程的常见实例就是JVM的GC线程。

五、线程中断

我们调用interupt()方法使得线程进入中断状态,这时线程内部的中断信号会被设置为true。我们要在线程的执行体中通过线程的中断检查事件(isInterrupted())判断有无进入中断状态,一般而言我们会用while(Thread.currentThread().isInterrupted()){}的语法。

六、线程常用API

1、设置线程本身属性

编号方法说明
1public final void setName(String name)设置线程名称
2public final void setPriority(int priority)设置线程优先级,默认为5
3public final void setDaemon(boolean on)将线程标记为守护线程或是用户线程

2、 其他常用方法

编号方法说明
1public  void  start()调用它使线程进入运行状态
2public void run()线程运行的任务
3public final void join();public final void join(long millisec)主线程等待该线程运行完毕
4public void interrupt()设置线程中断信号为true
5public final native boolean isAlive()判断线程是否处于运行状态
6public static Thread currentThread()返回当前的对象实例
7public static native void sleep(long millisec)当前线程交出CPU时间片但不释放对象锁,一般用于线程暂停
8public static native void yield()暂停当前执行的线程,线程进入限期等待状态

七、 常见问题

1、start()方法与run()方法有什么不同?

start()方法用于启动线程,使线程进入运行状态,而run()方法只是实现了线程任务的一个方法,单独运行run()方法只是让主线程去执行了一个普通方法,并没有创建新线程。

2、sleep()方法和wait()方法有什么不同?

①、sleep()方法只是阻塞了线程,并未释放锁,wait()方法释放了锁;②、sleep()是Thread类下的方法,wait()方法是Object类的;3、sleep()方法一般用于暂停线程,wait()通常用于线程间的交互和通信

3、yield()和sleep()有什么不同?

①、yield()方法执行后线程只是释放了当前的时间片,随时可以获取时间片重新运行,sleep则是进入等待状态,需要一定时间后才能重获时间片运行;2、yield()方法只会将CPU时间片获取机会给优先级相同或更高的线程,而sleep()方法则是一视同仁,任何线程都有机会获取时间片;3、sleep()必须声明InterruptedException而yield不必。

4、继承Thread类和实现Runnable接口有什么不同?

①我们都知道java只能单继承,而可以实现多个接口,实现Runnable后可以继承其他的类;②、实现Runnable接口,接口中的方法可以被其他线程共享。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值