多线程技术在互联网技术中应用如此广泛,以至于几乎所有后端技术面试官都不得不在并发编程的使用和原理上给小伙伴各种难关。作为一名在互联网科技行业打过几十万[请允许我夸大]的资深技术面试官,看到无数孤独的身影失望离去,心里有些愧疚,所以献上这篇文章,希望各位读者在未来,面试如雨后春笋,绝不会失败!如果觉得文章对你有帮助,可以点赞关注,给作者一点鼓励。什么是线程?线程是操作系统可以调度操作的最小单位。它包含在一个流程中,是流程中的实际操作单元。多线程可用于加速操作。比如一个线程完成一个任务需要100毫秒,那么十个线程完成这个任务只需要10毫秒。什么是多线程?的优点和缺点?什么是多线程?线程并发技术。多线程的好处:使用多线程可以把程序中长时间的任务放到后台处理,比如下载图片和视频可以发挥多核处理器的优势,并发执行让系统运行的更快更流畅,提升用户体验更好的多线程的缺点:大量的线程降低了代码的可读性;morethreadsrequiremorememoryspace当多个线程竞争同一个资源时,要注意线程安全问题。线程的五种状态(创建、就绪、运行、阻塞、死亡五种状态)?线程通常有五种状态,创建、就绪、运行、阻塞和死亡。***是创建状态。生成线程对象时,并没有调用该对象的start方法,即线程处于创建状态。二是就绪状态。当线程对象的start方法被调用时,线程进入就绪状态,但是此时线程调度器还没有将该线程设置为当前线程,所以处于就绪状态。线程运行后,从等待或休眠返回后,也会进入就绪状态。三是运行状态。线程调度器将处于就绪状态的线程设置为当前线程。这时线程进入运行状态,开始运行run函数中的代码。第四种是阻塞状态。当一个线程在运行时,它会被挂起,通常是等待一定的时间发生(例如,某个资源就绪),然后再继续运行。sleep、suspend、wait等方法都会造成线程阻塞。五是死亡状态。如果一个线程的run方法结束或者stop方法被调用,线程就会死亡。对于已经死亡的线程,不能再使用start方法让它就绪。什么是CAS?CAS(compareandswap)的缩写,中文翻译为比较和交换。CAS不经过JVM,直接使用java本地JNI(JavaNativeInterface是本地JAVA调用),直接调用CPU的cmpxchg(汇编指令)指令。利用CPU的CAS指令,同时利用JNI完成Java的非阻塞算法,实现原子操作。其他原子操作使用类似的属性执行。整个java.util.concurrent是基于CAS的,所以对于synchronized阻塞算法,J.U.C在性能上有很大的提升。CAS是一种乐观锁技术。当多个线程同时尝试使用CAS更新同一个变量时,只有一个线程可以更新变量的值,而其他线程则失败。失败的线程不会被挂起,而是被锁定。通知本次比赛失败,可以重试。CAS应用CAS有3个操作数,内存值V,旧的期望值A,待修改的新值B。当且仅当期望值A和内存值V相同时,修改内存值V为B,否则什么都不做。CAS的优点保证了对内存的读-修改-写操作都是原子操作。CAS的缺点是,虽然CAS在解决原子操作上效率很高,但是CAS仍然存在三大问题。ABA问题,循环时间长,开销大,只能保证共享变量的原子操作。什么是AQS?AbstractQueuedSynchronizer缩写为AQS,是一个构建锁和同步容器的框架。事实上,并发包中的很多类都是基于AQS实现的,比如ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock、FutureTask等,AQS在实现同步容器时解决了大量的设计细节问题。AQS使用FIFO队列来表示线程排队等待锁。队列头节点称为“哨兵节点”或“哑节点”,不与任何线程相关联。其他节点关联等待线程,每个节点维护一个等待状态waitStatus。什么是乐观锁和悲观锁?悲观锁Java在JDK1.5之前使用synchronized关键字来保证同步。通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有共享状态变量锁都以独占方式访问这些变量。独占锁其实就是悲观锁,所以可以说synchronized就是悲观锁。乐观锁乐观锁(OptimisticLocking)其实是一种思想。与悲观锁相比,乐观锁假设数据在正常情况下不会引起冲突,所以在提交更新数据时,会正式检测数据是否冲突。如果发现冲突,它会返回用户错误信息,让用户决定如何处理。并发编程(concurrency)和并行编程(parallelism)有什么区别?并发(concurrency)和并行(parallelism)是:解释1:并行是指两个或多个事件同时发生;事件发生在同一时间间隔。解释2:并行是不同实体上的多个事件,并发是同一实体上的多个事件。解释3:在一个处理器上“同时”处理多个任务,在多个处理器上同时处理多个任务。比如hadoop分布式集群,那么并发编程的目标就是充分利用处理器的每个核心,达到最好的处理性能。想了解更多多线程知识可以加群650385180,多线程学习资料和多线程面试题总结在群分享区免费下载。如何唤醒阻塞的线程?如果线程调用wait()、sleep()或join()方法引起的阻塞,可以中断线程并通过抛出InterruptedException将其唤醒;如果线程遇到IO阻塞,你也无能为力,因为IO是操作系统实现的,Java代码没有办法直接访问操作系统。如何检测死锁?如何防止死锁?所谓死锁:是指两个或多个进程在执行过程中因争夺资源而相互等待的现象。如果没有外力,他们都无法前进。这个时候,系统就说是死锁了。一般来说,就是两个或多个进程长时间阻塞,互相等待。死锁的原因?1、因竞争资源而产生死锁:当多个进程共享的资源数量不足以满足所有进程的需要时,就会造成资源竞争和死锁现象2、进程的进程顺序不当死锁的四个必要条件fordeadlock:互斥条件:进程不允许其他进程访问分配的资源。如果其他进程访问该资源,则只能等到占用该资源的进程使用完后释放该资源。请求和持有条件:进程获得某个资源后,请求其他资源,但该资源可能已被其他进程占用。这个请求被阻塞了,但是自己获得的资源却没有被剥夺。条件:指进程已经获得的资源。剥夺,使用后只能释放循环等待条件。是指一个进程发生死锁后,多个进程形成首尾相连的循环等待资源关系。这四个条件是死锁的必要条件,只要系统发生死锁,这些条件就必须成立,只要不满足上述条件之一,就不会发生死锁。有两种检测死锁的容器,一种用于持有线程正在请求的锁,另一种用于持有线程已经持有的锁。在每次加锁之前,都会进行如下检测:检测当前请求的锁是否已经被其他线程持有。如果是,找出那些线程,遍历第一步返回的线程,检查你持有的锁是否被任何一个线程请求,如果第二步返回true,则说明存在死锁死锁释放和预防:了解了死锁的原因,尤其是死锁的四个必要条件,就可以尽可能的避免、预防、解决死锁。因此,在系统设计、进程调度等方面,要注意如何防止这四个必要条件成立,如何确定合理的资源分配算法,避免进程腐败占用系统资源。此外,防止进程在等待状态时占用资源。因此,资源的分配应该给予合理的规划。想了解更多多线程知识点可以加群650385180,多线程学习资料和多线程面试题总结在群分享区免费下载。更多多线程面试题什么是原子操作?Java并发API中的原子类是什么?什么是执行器框架?什么是阻塞队列?如何使用阻塞队列来实现生产者消费者模型?什么是Callable和Future?什么是FutureTask?什么是同步容器和并发容器的实现?什么是多线程上下文切换?ThreadLocal的设计理念和作用?ThreadPool(线程池)的用法和优点?:ArrayBlockingQueue,CountDownLatch等synchronized和ReentrantLock有什么区别?信号量的作用是什么?JavaConcurrencyAPI中的Lock接口(Lock接口)是什么?我的眼光,所以写的可能不是很全面。如果有不同的意见,可以分享,一起交流。如果想了解更多多线程技术的知识点,可以加上面的群,希望能帮助到这个行业的发展各位童鞋们,少花点时间在论坛、博客等地方找资料,真正把有限的时间花在学习上。
