MST

星途 面试题库

面试题:Java接口泛型在多线程高并发环境下的类型安全设计与优化

设计一个多线程高并发的系统,其中有一个泛型接口`TaskExecutor<T>`,不同的实现类负责处理不同类型的任务`T`。在多线程环境下,要确保类型安全,避免数据竞争和类型转换错误。请详细阐述你的设计思路,包括如何使用锁机制、线程安全的数据结构以及如何处理泛型类型擦除带来的问题,并给出核心代码框架。
36.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 类型安全:通过泛型确保在编译时就明确任务类型,避免运行时类型转换错误。在接口和实现类中严格使用泛型,让编译器进行类型检查。
  2. 数据竞争
    • 锁机制:采用java.util.concurrent.locks.Lock接口及其实现类(如ReentrantLock)来控制对共享资源的访问。在任务处理涉及共享数据时,在进入处理逻辑前获取锁,处理完后释放锁。
    • 线程安全的数据结构:使用java.util.concurrent包下的线程安全数据结构,如ConcurrentHashMap用于存储任务相关数据,ConcurrentLinkedQueue用于任务队列。这些数据结构内部已经处理了线程安全问题,可避免数据竞争。
  3. 泛型类型擦除
    • 在泛型接口和实现类中定义方法时,尽量避免在运行时依赖泛型的具体类型。如果确实需要在运行时获取类型信息,可以使用Class<T>参数。在实现类构造函数中传入Class<T>对象,保存该对象用于运行时类型判断。

核心代码框架

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// 泛型接口
interface TaskExecutor<T> {
    void execute(T task);
}

// 具体任务类
class Task {
    // 任务相关属性和方法
}

// 具体任务执行类
class SpecificTaskExecutor implements TaskExecutor<Task> {
    private final Lock lock = new ReentrantLock();
    private final Class<Task> taskClass;

    public SpecificTaskExecutor(Class<Task> taskClass) {
        this.taskClass = taskClass;
    }

    @Override
    public void execute(Task task) {
        lock.lock();
        try {
            // 任务处理逻辑
            if (taskClass.isInstance(task)) {
                // 进行任务处理
            }
        } finally {
            lock.unlock();
        }
    }
}

// 多线程任务调度类
class TaskScheduler {
    private final ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
    private final TaskExecutor<Task> taskExecutor;

    public TaskScheduler(TaskExecutor<Task> taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    public void submitTask(Task task) {
        taskQueue.add(task);
    }

    public void start() {
        Thread thread = new Thread(() -> {
            while (true) {
                Task task = taskQueue.poll();
                if (task != null) {
                    taskExecutor.execute(task);
                }
            }
        });
        thread.start();
    }
}

使用示例

public class Main {
    public static void main(String[] args) {
        TaskExecutor<Task> executor = new SpecificTaskExecutor(Task.class);
        TaskScheduler scheduler = new TaskScheduler(executor);
        scheduler.submitTask(new Task());
        scheduler.start();
    }
}