深入理解-Java-多线程核心知识:跳槽面试必备.docxVIP

  • 1
  • 0
  • 约5.14千字
  • 约 10页
  • 2018-06-03 发布于江西
  • 举报

深入理解-Java-多线程核心知识:跳槽面试必备.docx

深入理解-Java-多线程核心知识:跳槽面试必备.docx

深入理解 Java 多线程核心知识:跳槽面试必备多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲。在平时工作中如若使用不当会出现数据错乱、执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关重要。本文从基础概念开始到最后的并发模型由浅入深,讲解下线程方面的知识。概念梳理本节我将带大家了解多线程中几大基础概念。并发与并行并行,表示两个线程同时做事情。并发,表示一会做这个事情,一会做另一个事情,存在着调度。单核 CPU 不可能存在并行(微观上)。临界区临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。阻塞与非阻塞阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。阻塞是指线程在操作系统层面被挂起。阻塞一般性能不好,需大约8万个时钟周期来做调度。非阻塞则允许多个线程同时进入临界区。死锁死锁是进程死锁的简称,是指多个进程循环等待他方占有的资源而无限的僵持下去的局面。活锁假设有两个线程1、2,它们都需要资源 A/B,假设1号线程占有了 A 资源,2号线程占有了 B 资源;由于两个线程都需要同时拥有这两个资源才可以工作,为了避免死锁,1号线程释放了 A 资源占有锁,2号线程释放了 B 资源占有锁;此时 AB 空闲,两个线程又同时抢锁,再次出现上述情况,此时发生了活锁。简单类比,电梯遇到人,一个进的一个出的,对面占路,两个人同时往一个方向让路,来回重复,还是堵着路。如果线上应用遇到了活锁问题,恭喜你中奖了,这类问题比较难排查。饥饿饥饿是指某一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行。线程的生命周期在线程的生命周期中,它要经历创建、可运行、不可运行几种状态。创建状态当用 new 操作符创建一个新的线程对象时,该线程处于创建状态。处于创建状态的线程只是一个空的线程对象,系统不为它分配资源。可运行状态执行线程的 start() 方法将为线程分配必须的系统资源,安排其运行,并调用线程体——run()方法,这样就使得该线程处于可运行状态(Runnable)。这一状态并不是运行中状态(Running),因为线程也许实际上并未真正运行。不可运行状态当发生下列事件时,处于运行状态的线程会转入到不可运行状态:调用了 sleep() 方法;线程调用 wait() 方法等待特定条件的满足;线程输入/输出阻塞;返回可运行状态;处于睡眠状态的线程在指定的时间过去后;如果线程在等待某一条件,另一个对象必须通过 notify() 或 notifyAll() 方法通知等待线程条件的改变;如果线程是因为输入输出阻塞,等待输入输出完成。线程的优先级线程优先级及设置线程的优先级是为了在多线程环境中便于系统对线程的调度,优先级高的线程将优先执行。一个线程的优先级设置遵从以下原则:线程创建时,子继承父的优先级;线程创建后,可通过调用 setPriority() 方法改变优先级;线程的优先级是1-10之间的正整数。线程的调度策略线程调度器选择优先级最高的线程运行。但是,如果发生以下情况,就会终止线程的运行:线程体中调用了 yield() 方法,让出了对 CPU 的占用权;线程体中调用了 sleep() 方法,使线程进入睡眠状态;线程由于 I/O 操作而受阻塞;另一个更高优先级的线程出现;在支持时间片的系统中,该线程的时间片用完。单线程创建方式单线程创建方式比较简单,一般只有两种方式:继承 Thread 类和实现 Runnable 接口;这两种方式比较常用就不在 Demo 了,但是对于新手需要注意的问题有:不管是继承 Thread 类还是实现 Runable 接口,业务逻辑是写在 run 方法里面,线程启动的时候是执行 start() 方法;开启新的线程,不影响主线程的代码执行顺序也不会阻塞主线程的执行;新的线程和主线程的代码执行顺序是不能够保证先后的;对于多线程程序,从微观上来讲某一时刻只有一个线程在工作,多线程目的是让 CPU 忙起来;通过查看 Thread 的源码可以看到,Thread 类是实现了 Runnable 接口的,所以这两种本质上来讲是一个;PS:平时在工作中也可以借鉴这种代码结构,对上层调用来讲提供更多的选择,作为服务提供方核心业务归一维护为什么要用线程池通过上面的介绍,完全可以开发一个多线程的程序,为什么还要引入线程池呢。主要是因为上述单线程方式存在以下几个问题:线程的工

文档评论(0)

1亿VIP精品文档

相关文档