本文主要是介绍Java面试之线程常见问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.如何停止一个正在运行的线程
使用退出标志,使线程正常退出,也就是当run方法完成后线程终止 使用stop 方法强行终止 使用interrupt打断线程
2.线程中sleep和wait有什么区别?
相同点 :sleep和wait都是用来控制线程的
不同点 :
sleep是Thread类(自控)中的方法,wait是Object (他控)中的方法 sleep可以在任何地方使用,wait只能在synchronized方法或者synchronized使用 调用sleep方法,会让出cpu,不会导致锁行为的改变;调用wait方法,不仅会让出cpu,还是释放已经占有的同步资源锁
3.启动一个线程是用run()还是start()?
启动线程是start(),线程启动后就会处于可运行状态,但不一定马上执行run()方法,当cpu分配给它时间时,才开始执行run()方法,start方法调用run方法,run方法是你要重写的程序逻辑,run方法包含的是线程的主体。
4.如何保证线程的运行安全?
原子性 :提供互斥访问,同一时刻只能由一个线程对数据进行操作。可见性 :一个线程对主内存的修改可以及时被其他线程看到有序性 :一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序。
5.线程同步的几种方法:
使用synchronized 关键字 wait 和notify 方法使用特殊域变量volatile 实现线程同步 使用可重入锁实现线程同步 使用阻塞队列实现线程同步‘ 使用信号量semaphone
6.创建线程的方法:
继承Thread类 实现Runnable接口 通过Callable和Future创建线程 通过线程池创建线程
7.Runnable和Callable区别:
Runnable接口中的run方法的返回值是void,即没有返回值,纯碎是执行run方法中的代码 Callable接口中的call方法的返回值是一个Object泛型,和Future,FutureTask配合可以用来获取异步执行的结果。
8.ThreadLocal类使用:
每一个线程独享一个ThreadLocal,在接受请求时set特定的内容,在需要的时候get这个值.如:
public class HostHolder {
private ThreadLocal<User> users = new ThreadLocal<>();
public void setUser(User user) {
users.set(user);
}
public User getUser() {
return users.get();
}
public void clear(){
users.remove();
}
}
set方法是用来设置当前线程中变量的副本 get方法是用来获取ThreadLocal在当前线程中保存的变量的副本。 remove方法用来移除当前线程中变量的副本 clear方法用来清空当前线程保存的变量的副本 此外还有initialValue方法,一般用来在使用时进行重写。如果在没有set的时候就调用get,会自动调用initialValue方法初始化内容
9.为什么要使用线程池:
线程池主要提供了一种限制和管理资源的方式,每个线程池还维护了一些基本统计信息,例如:已完成任务的数量.
使用线程的优点:
降低资源的消耗 :通过重复利用已经创建的线程降低线程创建和销毁造成的消耗;提高响应速度 :当任务到达时,任务可以不需要等到线程创建就能立即执行;提高线程的可管理性 :使用线程池可以进行统一的分配,调优,和监控
10.如何创建线程池:
通过ThreadPoolExecutor的构造方法实现 通过Executor框架的工具类Executor来实现,该工具类提供三种类型的ThreadPoolExecutor:
FixedThreadPool : 该方法返回一个固定线程池数量的线程池,该线程池中的线程数量始终不变。SingleThreadExecutor : 该方法返回一个只有一个线程的线程池。CachedThreadPool :该方法返回一个只有一个可根据实际情况调整,即线程池的线程数量不确定,但若有空闲的线程可以复用,优先使用可复用的线程。
这篇关于Java面试之线程常见问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!