Java 多线程基础面试
1. 什么是线程?
线程是操作系统能够进行运算调度的最小单位,是被系统独立调度和分派的基本单位。
2. 什么是进程?
进程是操作系统进行资源分配和调度的基本单位。
3. 线程和进程有什么区别?
- 进程拥有独立的内存空间,而线程共享进程的内存空间。
- 进程切换开销大,线程切换开销小。
- 进程适合进行大量的计算工作,线程适合执行短小的、频繁切换的任务。
4. Java中如何创建线程?
- 继承
Thread
类并重写run
方法。 - 实现
Runnable
接口并实现run
方法。 - 使用
Callable
接口和Future
类。
// 继承Thread类
class MyThread extends Thread {
public void run() {
// 线程执行的操作
}
}
// 实现Runnable接口
class MyRunnable implements Runnable {
public void run() {
// 线程执行的操作
}
}
// 使用Callable接口
class MyCallable implements Callable<Integer> {
public Integer call() {
return 123;
}
}
5. 线程有哪些状态?
线程的状态包括:新建、就绪、运行、阻塞和死亡。
6. 什么是线程调度?
线程调度是指系统对多个线程进行调度,分配CPU时间。
7. 什么是上下文切换?
上下文切换是CPU从一个线程切换到另一个线程的过程。
8. Java中如何实现线程间的同步?
使用synchronized
关键字,ReentrantLock
类,Semaphore
类等。
public synchronized void myMethod() {
// 需要同步的代码块
}
9. 什么是死锁?
死锁是指两个或多个线程在等待对方释放资源,导致程序无法继续执行。
10. 如何避免死锁?
避免死锁的方法包括:避免资源嵌套锁定、使用超时锁定、有序锁定资源等。
11. 什么是线程安全?
线程安全是指当多个线程访问某个类或代码块时,能够正确地处理多个线程的并发操作。
12. Java中有哪些线程池?
Java中的线程池包括FixedThreadPool
、CachedThreadPool
、ScheduledThreadPool
和SingleThreadExecutor
。
ExecutorService threadPool = Executors.newFixedThreadPool(10);
13. 线程池有什么作用?
线程池可以减少线程创建和销毁的开销,提高系统资源利用率,提高程序响应速度。
14. 什么是`Executor`框架?
Executor
框架是一个用于管理线程的框架,它提供了一种简单高效的方法来启动和管理线程。
15. `Runnable`接口和`Callable`接口有什么区别?
Runnable
接口返回void
,Callable
接口可以返回泛型类型,并且可以抛出异常。
16. Java中如何中断线程?
使用interrupt
方法中断线程。
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 线程执行的操作
}
});
thread.start();
thread.interrupt(); // 中断线程
17. Java中如何等待线程结束?
使用join
方法等待线程结束。
Thread thread = new Thread(() -> {
// 线程执行的操作
});
thread.start();
thread.join(); // 等待线程结束
18. Java中如何实现守护线程?
使用setDaemon(true)
将线程设置为守护线程。
Thread thread = new Thread(() -> {
// 线程执行的操作
});
thread.setDaemon(true);
thread.start();
19. Java中如何获取当前线程?
使用Thread.currentThread()
方法获取当前线程。
Thread currentThread = Thread.currentThread();
20. Java中如何设置线程的优先级?
使用setPriority
方法设置线程的优先级。
Thread thread = new Thread(() -> {
// 线程执行的操作
});
thread.setPriority(Thread.MAX_PRIORITY);
21. Java中如何获取线程的堆栈跟踪?
使用Thread
类的getStackTrace()
方法获取堆栈跟踪。
Thread thread = new Thread(() -> {
// 线程执行的操作
});
StackTraceElement[] stackTrace = thread.getStackTrace();
22. Java中如何实现线程的睡眠?
使用Thread.sleep()
方法使当前线程睡眠。
try {
Thread.sleep(1000); // 睡眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
23. Java中如何实现定时器?
使用Timer
类和TimerTask
类实现定时器。
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// 定时任务执行的操作
}
}, 1000, 1000); // 1秒后开始执行,每隔1秒执行一次
24. Java中如何实现周期性任务?
使用ScheduledExecutorService
实现周期性任务。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
// 周期性任务执行的操作
}, 0, 1, TimeUnit.SECONDS);
25. Java中如何实现单例模式的线程安全?
使用双重检查锁定模式或静态内部类模式实现线程安全的单例模式。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
26. Java中如何实现线程通信?
使用wait
、notify
和notifyAll
方法实现线程通信。
public class Communicate {
private boolean ready = false;
public synchronized void doSomething() {
while (!ready) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 处理数据
}
public synchronized void prepareData() {
ready = true;
notifyAll();
}
}
27. Java中如何实现线程的优雅停止?
使用标志位和interrupt
方法实现线程的优雅停止。
public class GracefulStop {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void doWork() {
while (running) {
// 线程执行的操作
}
}
}
28. Java中如何捕获线程中的异常?
使用UncaughtExceptionHandler
捕获线程中的异常。
Thread thread = new Thread(() -> {
try {
// 线程执行的操作
} catch (Exception e) {
// 处理异常
}
});
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
// 处理异常
}
});
thread.start();
29. Java中如何实现线程的局部存储?
使用ThreadLocal
类实现线程的局部存储。
public class ThreadLocalExample {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(() -> {
threadLocal.set(10);
System.out.println(threadLocal.get());
}).start();
}
}
30. Java中如何实现并发数据结构?
使用java.util.concurrent
包中的并发数据结构,如ConcurrentHashMap
、CopyOnWriteArrayList
等。
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("key", "value");
31. Java中如何实现原子操作?
使用java.util.concurrent.atomic
包中的原子类,如AtomicInteger
、AtomicLong
等。
AtomicInteger atomicInteger = new AtomicInteger(0);
atomicInteger.incrementAndGet();
32. Java中如何实现锁?
使用synchronized
关键字和ReentrantLock
类实现锁。
Lock lock = new ReentrantLock();
lock.lock();
try {
// 需要同步的代码块
} finally {
lock.unlock();
}
33. Java中如何实现公平锁?
使用ReentrantLock
类的true
参数构造函数实现公平锁。
Lock fairLock = new ReentrantLock(true);
34. Java中如何实现读写锁?
使用ReadWriteLock
和ReentrantReadWriteLock
类实现读写锁。
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
35. Java中如何实现条件变量?
使用Condition
接口和await