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中的线程池包括FixedThreadPoolCachedThreadPoolScheduledThreadPoolSingleThreadExecutor

ExecutorService threadPool = Executors.newFixedThreadPool(10);

13. 线程池有什么作用?

线程池可以减少线程创建和销毁的开销,提高系统资源利用率,提高程序响应速度。

14. 什么是`Executor`框架?

Executor框架是一个用于管理线程的框架,它提供了一种简单高效的方法来启动和管理线程。

15. `Runnable`接口和`Callable`接口有什么区别?

Runnable接口返回voidCallable接口可以返回泛型类型,并且可以抛出异常。

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中如何实现线程通信?

使用waitnotifynotifyAll方法实现线程通信。

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包中的并发数据结构,如ConcurrentHashMapCopyOnWriteArrayList等。

ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("key", "value");

31. Java中如何实现原子操作?

使用java.util.concurrent.atomic包中的原子类,如AtomicIntegerAtomicLong等。

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中如何实现读写锁?

使用ReadWriteLockReentrantReadWriteLock类实现读写锁。

ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();

35. Java中如何实现条件变量?

使用Condition接口和await