多线程高频面试题
1. 说说进程和线程的区别?
- 进程是操作系统中程序运行的实例,每个进程都有独立的内存空间、系统资源、执行状态,进程间相互独立,在进行多任务处理时,多个进程可以并发执行。
- 线程是进程中的执行单元,同一个进程中的线程共享内存空间和系统资源,线程之间的通信和协作比较方便,在高并发的场景下,多线程能够有效提高程序性能。
2. 为什么要使用多线程?
- 提高程序的并发性:多线程可以让程序同时执行多个任务,从而提高程序的并发性和响应速度。
- 充分利用系统资源:多线程可以充分利用多核处理器和多内存等系统资源,提高系统的利用率和性能。
- 实现复杂的功能:多线程可以用于实现一些复杂的功能,如网络通信、数据库操作等,从而提高程序的灵活性和可扩展性。
- 提高程序的可靠性:多线程可以采用锁机制来保证多个线程之间的数据同步和互斥,从而提高程序的可靠性和稳定性。
3. 如何在Java中创建一个多线程?
- 继承 Thread 类,并重写 run() 方法。
代码示例:
//一个线程方法
public class MyThread extends Thread {
public void run(){
//线程执行代码
}
}
//在主线程中创建MyThread()对象,使用start()方法启动线程
MyThread thread =new MyThread();
thread.start();
- 实现 Runnable 接口,并将其作为参数传递给 Thread() 类的构造方法。
代码示例:
public class MyRunnable implements Runnable {
public void run(){
//线程执行代码
}
}
//在主线程中创建MyRunnable对象,并启动线程
MyRunnable runnable=new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
- 实现 Callable 接口,如果要在线程中返回一个结果,可以使用该方式。
代码示例:
public class MyCallable implements Callable<Integer> {
public Integer call() throws Exception {
// 线程执行的代码,返回一个结果
return result;
}
}
// 在主线程中创建MyCallable对象并提交到ExecutorService中执行
MyCallable myCallable = new MyCallable();
Future<Integer> future = executorService.submit(myCallable);
int result = future.get(); // 等待线程执行完毕并获取结果
4. 线程状态有哪些?
Java中线程有六种状态,分别是:
- 新建状态(New):当线程对象被创建时,它就进入了新建状态。
- 就绪状态(Ready):当线程获得除CPU以外的所有资源时,线程就会进入就绪状态。
- 运行状态(Running):当线程获得CPU时间片,并且开始执行run()方法时,线程就进入运行状态。
- 阻塞状态(Blocked):当线程由于一些原因无法继续执行时,就会进入阻塞状态。例如一个线程试图访问一个已经被其它线程占用对象。
- 等待状态(Waiting):当线程需要等待某个条件满足时,它就进入了等待状态。例如一个线程需要等待另一个线程执行完时才能继续执行,
- 计时等待状态(Timed_Waiting):当你使用 Thread.sleep() 方法设置休眠时间,线程就会进入即使等待状态。
5. 如何让线程休眠?
在Java中,可以使用Thread.sleep()方法让线程休眠一段时间。该方法接受一个时间参数,表示线程需要休眠多长时间。例如,以下代码会让线程休眠5秒钟后继续执行:
try {
Thread.sleep(5000); // 休眠5秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
6. 什么是死锁?如何让避免死锁?
死锁是指两个或多个进程相互等待对方释放资源,导致所有线程都无法继续执行的情况,避免死锁的方式有:
1.避免嵌套锁:如果一个线程已经持有了某个对象的锁,那么它应该避免再次获取该对象的其他锁,以免出现死锁。
2.统一加锁顺序:对于多个锁,应该按照一定的顺序加锁,避免出现交叉加锁的情况。
3.设置超时时间:在获取锁的过程中,可以设置一个超时时间,如果在指定时间内没有获取到锁,就放弃自身持有的锁。
4.避免共享资源:尽量避免多个线程共享同一个资源,或者对同一个资源进行多次操作。这样可以减少出现死锁的可能性。
7. 什么是线程池?优点是什么?
线程池是一种利用池化思想管理线程的技术,将任务创建与线程创建解耦开来,便于线程的管理,通过线程复用降低频繁创建和销毁线程带来的资源消耗,Java中主要通过ThreadPoolExcutor类创建线程池。
线程池的优点:
降低资源消耗,复用已创建的线程来降低创建和销毁线程的消耗。
提高响应速度,任务到达时,可以不需要等待线程的创建立即执行。
提高线程的可管理性,使用线程池能够统一的分配、调优和监控。