1、什么是线程?线程和进程有什么区别?
答:线程是程序执行的最小执行单位,进程是资源分配的最小单位;一个进程就是一个应用程序,系统会为该进程分配资源空间,当多用户并发请求的时候,为每个用户创建一个进程资源开销太大难以实现,就开辟了线程,线程速度比较快,线程之间共享进程之间的内存资源。
2、如何在Java中实现线程?
有四种实现方法:
1)继承Thread类
2)实现Runnable接口
3)实现Callable接口通过FutureTask包装器来创建Thread线程、
4)使用ExecutorService、Callable、Future实现有返回结果的多线程。
其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。一般知道前两种方法就行了。
3、Java 关键字volatile 与 synchronized 作用与区别?
答:线程有几个特性
原子性:不被其他线程中断
可见性:执行结果其他线程可以看到
顺序性:保证线程操作的执行顺序
volatile 只能用来修饰变量、作用范围较小; synchronized可以修饰变量、方法、类和代码块。
volatile 修饰的变量在线程未结束的时候就可以被其他线程读取,不能保证原子性;
synchronized则保证线程执行完成后变量结果值才可见,保证了原子性、可见性和顺序性。
4、线程有哪些不同的线程生命周期?
新建状态
就绪状态
运行状态
阻塞状态
终止状态
5、什么是死锁(Deadlock)?如何分析和避免死锁?
死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
避免死锁就要避免循环等待条件的产生,设置资源标识位以及执行顺序等。
6、什么是线程安全?Vector是一个线程安全类吗?
线程安全就是,多线程操作,和多个单独线程同时操作产生得结果一样。
一般认为Vector是一个线程安全的类,但实际上虽然Vector类中好多方法是用Synchronized修饰的,但是也有remove 和 contains等几个方法不是用Synchronized修饰的,这样就需要在业务代码块中添加同步锁,所以严格来说不能直接说Vector是线程安全类。
7、Java中如何停止一个线程?()
Thread类中的interrupt()方法可以中断线程. 注意调用interrupt()方法仅仅是在当前线程打一个中断标志,并不是真正的停止线程. 调用Thread.interrupted()静态方法可以判断当前线程的中断状态,也可以调用thread.isInterrupted()实例方法判断当前线程的中断状态. 这两个方法的区别在于: 静态方法interrupted()判断完中断状态后会清除中断标志, 实例方法isInterrupted()判断完后不会清除中断标志.
8、Sleep()、suspend()和wait()之间有什么区别?
答:Sleep()固定时间后主动唤醒,suspend()是已经废弃的暂停方法、被resumen唤醒,wait()被notifywai唤醒
9、什么是线程饿死,什么是活锁?
饿死:线程没有被合理的分配资源,都处于无限期的等待;
活锁:所有线程都认为自己的优先级别不够高,都在等待对方先执行。
10、什么是Java Timer类?如何创建一个有特定时间间隔的任务?
答:Timer可以看成一个定时器,用来安排以后在线程中执行的任务,可设置任务执行一次,或者定期重复执行。Timer可以调度TimerTask创建有特定时间间隔的任务,TimerTask是一个抽象类,实现了Runnable接口,所以具备了多线程的能力;一个Timer可以调度任意多个TimerTask,它会将TimerTask存储在一个队列中,顺序调度,如果想两个TimerTask并发执行,则需要创建两个Timer。
11、什么是线程池? 为什么要使用它?
答:线程池用来管理多线程任务中的线程;一个线程需要创建,运行和销毁,如果客户端访问量过大,那么创建线程和销毁线程将是一笔很大的开销,有了线程池,可以将运行完成的线程暂时放在线程池中,当新的请求过来的时候,直接用就可以,当然线程池容量也不易过多。
创建线程和销毁都是需要时间和资源的,如果任务来了才去创建线程,显然是不对的,我们会在程序启动的时候事先放入几个线程,当有任务调用的时候就直接去链接线程池中的线程,任务结束再放回线程池,线程不易创建太多,线程之前的切换也很耗费资源。
12、多线程中的忙循环是什么?
答: 忙循环就是程序员用循环让一个线程等待;不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制,而忙循环不会放弃CPU,它就是在运行一个空循环。这么做的目的是为了保留CPU缓存。在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存,为了避免重建缓存和减少等待重建的时间就可以使用忙循环。
13、Thread 类中的start() 和run() 方法有什么区别?
1)start 是用来启动线程的,run()则是运行线程的 ;
2)start 在一个线程中只能调用一次,而run则可以多次调用;
3)查看Thread类的源码会发现start 有synchronized的修饰,可见这个方法是线程安全的。
14、在多线程中,什么是上下文切换?
答:cpu通过给每个线程分配时间片来存储和回复线程的状态,一般因为时间非常短,所以cpu通过不断地切换线程,让我们感觉多个线程是同时执行的,一般时间片为几十毫秒。
15、(相对于线程来说)Java中堆和栈有什么不同?
答:创建的对象是在堆中,堆内存是线程内存共享的区域;而栈中内存是线程私有的区域、生命周期随着线程的消亡而消亡。系统为了提高运行效率会从堆中复制一份变量到栈中,运行完成后再刷新到主内存中。
16、Thread类中的yield方法有什么作用?
答:让当前正在运行的线程回到就绪状态,让出cpu,等待cpu的再次调度。
17、Java中notify 和 notifyAll有什么区别?
答:notify是唤醒等待池中的某一个线程但是不指定是那个,notifyAll是唤醒等待池中的所有线程进入锁池中竞争对象。
18、Java中interrupted 和 isInterruptedd方法的区别?
interrupt() 是静态方法,向当前线程发出中断信号
isinterrupted() 查看当前中断信号是true还是false
19、Java多线程中调用wait() 和 sleep()方法有什么不同?
答:sleep()是Thread的静态方法,线程调用此方法会让线程暂时放弃cpu资源供其他线程使用,但是不会释放对象锁,时间到后会自动苏醒,但是不会立即执行线程,需要捕获异常
wait()方法必须放在同步控制方法或者同步语句块中使用,会暂时放弃对象锁,然后此线程进入阻塞状态,等notify()方法讲起唤醒进入待运行状态。
20、有三个线程T1,T2,T3,怎么确保它们按顺序执行?
启动某个线程的时候分别加入join()方法,例如T3调用T2然后T2调用T1,利用单线程池法
21、什么是ThreadLocal?
ThreadLocal是局部本地变量,为单个线程私有变量、不能共享,所以不存在线程安全问题;
想对的还有共享变量,线程不安全,需要用锁机制来维护。
22、Java线程池中submit() 和 execute()方法有什么区别?
答:两个方法都可以向线程池中提交任务,区别是:
execute()是Executor中的方法,用void修饰,即没有返回值;
submit() 是ExecutorService中的方法,有返回值,返回值为Future对象,可以用get方法获取执行结果。
23、Java中Runnable和Callable有什么不同?
答:都代表那些在不同线程中执行的任务,区别是:
1)Runnable从jdk1.0就有,Callable从jdk5.0有;
2)callabel的call()方法可返回Future对象,Runnable的run()方法没有返回值。



