赞
踩
问题一:并行和并发的区别?
问题二:线程和进程的区别?
答:先写一个式子:
一个程序=n个进程;一个进程=n个线程;
问题三:守护线程?
答:即daemon thread,是服务线程,服务其他线程。GC就是一个。
问题四:创建线程的方式?
答:有三种方式
问题五:runnable和callable有什么区别?
答:Runnable的run方法没有返回值,只是执行了一下run方法;
Callable的call方法有返回值,是一个泛型,和Future和FutureTask配合可以获取异步执行结果。
Callable接口的call方法允许抛出异常,run方法只能内部消化,不能继续向上抛。
其中FutureTask的get方法会阻塞主进程向下执行,不调用不会
问题六:线程的状态?
答:创建、就绪、运行、阻塞、死亡。
我的理解就像接力赛跑一样,当运动员进场,线程创建;准备声响起,线程就绪;发令声响起,线程运行;如果不小心接力棒掉了或没接力好,线程就会阻塞;当跑完全程,线程死亡。
问题七:sleep和wait的区别?
问题八:notify()和notifyAll()的区别?
问题九:线程run()和start()的区别
问题十:创建线程池有几种方式?
1.newFixedThreadPool(int),创建一个固定长度的线程池,美当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程。
2.newCachedThredaPool,创建一个可缓存的线程池,如果线程池规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制。
3.newScheduledThreadPool,创建一个固定长度的线程池,可执行周期性的任务。
4.newSingleThreadExecutor,创建单线程的线程池,线程异常结束,会创建一个新的线程,确保任务提交按顺序执行。
还有其他的创建线程池的方式
问题十一:线程池有哪些状态?
Running、ShutDown、Stop、Tidying、Terminated。
RUNNING:这是最正常的状态,接受新的任务,处理等待队列中的任务。线程池的初始状态就是Running。线程池一旦创建,就处于Running状态,并且其中任务数为0
SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务。调用shutdown方法,线程池由RUNNING进入SHUTDOWN状态。
STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。调用线程池shutdownNow方法,线程池由running 或shutdown进入STOP状态。
TIDYING:所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()。因为terminated()在ThreadPoolExecutor类中是空的,所以用户想在线程池变为TIDYING时进行相应的处理;可以通过重载terminated()函数来实现。当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。
TERMINATED:terminated()方法结束后,线程池的状态就会变成这个。
问题十二:线程池中 submit()和 execute()方法有什么区别?
问题十三:再Java中怎么保证多线程运行安全?
缓存会导致可见性问题
线程切换会导致原子性问题
编译优化会带来有序性问题。
使用安全类,Java.util.concurrent下的类、synchronized、LOCK可以解决原子性问题
synchronized、volatile、LOCK可以解决可见性问题
Happens-Before规则可以解决有序性问题
Happens-Before规则如下:
问题十四:多线程锁升级的原理是什么?
锁共有四种状态:无状态锁、偏向锁、轻量级锁、重量级锁;这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。
锁分级别的原因:没有优化以前,synchronized是重量级锁(悲观锁),使用wait、notify、notifyall来切换线程非常消耗系统资源,线程的挂起和唤醒间隔很短暂,这样很浪费资源,影响性能。所有JVM对关键字synchronized进行了优化,分为无锁、偏向锁、轻量级锁、重量级锁。
偏向锁的撤销,需要某个时间没有字节码正在执行,先暂停偏向锁的线程,然后判断锁对象是否处于被锁定状态,如果线程不处于活动状态,则将对象头设置为无锁状态,并撤销偏向锁。如果处于活动状态,则升级为轻量级锁。
问题十五:什么是死锁?
两个或两个以上的进程在执行过程中,由于竞争资源或彼此通信而造成的一种阻塞现象,若无外力作用,则永久阻塞下去。死锁是操作系统层面的一个错误,是进程死锁的简称,是整个计算机操作系统乃至整个并发程序设计领域最难处理的问题之一。
问题十六:怎么防止死锁?
死锁的四个必要条件:
只要上述四个条件之一不满足,就不会死锁;
减少同步代码块嵌套;降低锁的使用粒度,不要几个功能共用一把锁;尽量采用tryLock(timeout)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间;使用concurrent并发类代替手写锁。
问题十七:ThreadLocal是什么?有哪些使用场景?
ThreadLocal类支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如web服务器)使用线程局部变量,ThreadLocal的生命周期比线程的生命周期都长;如果ThreadLocal在工作完成后没有释放,就存在内存泄漏的风险。
ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本而不影响其他线程对应的副本。
经典使用场景:数据库连接,这样每个线程都在各自的Connection进行数据库操作和session管理等。
问题十八:说一下synchronized底层实现原理?
synchronized可以保证方法或代码块在运行时,只有一个方法可以进入,同时还可以保证共享变量的可见性。Java中每一个对象都可以作为锁,这是synchronized实现同步的基础;作用在方法上,锁的是当前实例对象;作用在静态方法上,锁的是当前类的class对象;作用在方法块,锁的是括号里面的对象。
synchronized是由一对monitorenter/monitorexit指令实现,monitor对象是同步的基本实现单元。在Java6之前,monitor实现完全依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步是一个无差别的重量级操作,性能低;Java6时,JVM提供了monitor三种不同的实现,也就是偏向锁,轻量级锁,重量级锁,改进了性能。
问题十九:synchronized和volatile的区别是什么?
问题二十一:synchronized和ReentrantLock有什么区别?
问题二十二:说一下atomic的原理?
Atomic包中的类基本的特性就是在多线程环境下,当有多个线程同时对单个变量进行操作时,具有排他性。atomic主要利用CAS和volatile和native方法保证原子操作,从而避免synchronized的高开销,提高执行效率。
Atomic系列的类中核心方法都会调用unsafe类中的几个本地方法。unsafe类,sun.misc.Unsafe,这个类包含大量对C代码的操作,包括很多直接内存分配及原子操作的调用,而它之所以标记为非安全的就是告诉你这里面的方法调用都会存在安全隐患,需要小心使用,否则会导致严重后果;例如你在通过unsafe分配内存的时候,如果指定某些区域可能会导致一些类似C++一样的指针越界到其他进程的问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。