1.什么是线程?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix
System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel
thread),而把用户线程(user thread)称为线程。程序由线程构成。
2.什么是线程安全?
线程安全是:当一个类或者方法在不需要其他类或方法协同辅助时被任意调用,仍然能保持内部数据正确且逻辑正确,那这个类或方法是线程安全的。
3.什么类是线程安全的?
被final修饰的类、enum类、线程兼容类(使用synchronized控制同步的类)、java.util.concurrent下的类。
4.什么是线程的同步、异步?
同步
线程A调用线程B,只有当线程B处理完自身逻辑之后(此时线程A处于阻塞等待状态),才能返回给线程A。比如A向B发消息,B没回,A就只能等着,直到B发了消息。常见应用场景:搜索(任何搜索引擎比如百度,只有等处理完数据才能显示)、固定流水线流程(别人做完自己才能做)
转换如图:
异步
线程A调用线程B,线程B立即返回给线程A某临时数据(比如接受成功提示),当线程B处理完逻辑之后(此时线程A处于运行状态),再将结果返回给线程A。比如A向B发消息,B发送本人繁忙消息,A就做其他事情。常见应用场景:任何耗时任务(比如用户下订单,在用户下完订单之后,先提示订单完成,之后提示其他有关订单的非必要信息)
转换如图:
二者对比
优势 | 劣势 | |
---|---|---|
同步 | 逻辑处理直观实时 | 耗时长 |
异步 | 节省时间,节省资源 | 需要很多异步任务保证数据逻辑正确 |
5.什么是阻塞、非阻塞?
阻塞
同步时,线程A调用线程B,线程B未返回结果,此时线程A处于阻塞状态(等待中且对应线程被挂起)
非阻塞
异步时,线程A调用线程B,即便线程B未返回结果,线程A也在正常运行,此时线程A处于非阻塞状态(运行中且对应线程不挂起)
6.什么是并发、并行?
并发
并不一定是同时进行但表现出同时多个处理,比如百度网盘多个文件同时在下载但是实际是cpu分微小时间段进行单个处理。
如图:
并行
一定是同时进行也表现出同时多个处理,比如两个cpu同时在下载两个文件,那么这两个文件就处于并行状态。
如图:
7.线程的六个状态及关联?
六种状态
NEW:线程创建但是还没有调用start()方法
RUNNABLE :可运行线程的状态,线程已经在JVM虚拟机中执行,但是可能需要等待操作系统资源,如处理器。RUNNABLE包括RUNNING和READY
BLOCKED :阻塞的线程意味着正在等待监视器锁,来进入或重入synchronized代码块或者方法
WAITING :等待状态,需要其他线程中断或通知来唤醒
TIMED_WAITING :定时等待状态,在指定等待时间后返回,或提前被其他线程中断或通知返回
TERMINATED :终止线程的线程状态,线程已执行完成
关联如图:
大致描述:
- 线程Anew之后变为运行态。
- 运行态通过上述命令可变为等待、超时等待、阻塞三种状态。三种状态也可变为运行态
- 运行态线程执行完成终止。
线程的java操作:
1.Thread.yield()
简言之,让步。比如线程A,B先后调用某资源。当某时刻A.yield,那么立即由B使用该资源,B执行完成后,A在继续执行。
2.Thread.sleep()
简言之:暂时睡眠。比如线程A,B先后调用某资源。当某时刻A.sleep,那么等A睡眠结束后完成该资源调用,B才能开始使用。
3.Thread.join()
简言之:立即加入。比如线程A,B先后调用某资源。当某时刻A.sleep,随后B.join()那么B立即开始使用该资源。等A睡眠结束后也只有B完成了,A才能继续使用该资源。
4.Object.wait()
简言之:等待。Object类的方法,调用前必须拥有对象锁,比如在synchronized代码块内,调用wait方法后,对象锁会释放,线程进入WAITING等待状态
8.什么是死锁?
网上百度为:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
个人解释为:多线程抢占多个锁,抢占顺序不相同。那么A抢占到了资源锁a,想去抢占其他线程已占有的锁,抢占不到。而其他线程想抢占线程A所占有的锁也抢占不到。这样就出现了死锁。
9.如何处理死锁?
1.尝试获取超时释放的锁。比如lock的trylock来获取锁
2.发生程序锁时,重启程序。