面试题答案
一键面试1. 线程工厂接口设计
定义一个通用的线程工厂接口,例如 MyThreadFactory
,它应该至少包含一个创建线程的方法:
public interface MyThreadFactory {
Thread newThread(Runnable r);
}
2. 实现通用线程工厂类
创建一个具体的通用线程工厂类,例如 DefaultMyThreadFactory
,来实现上述接口。在这个类中,可以进行一些通用的线程配置,如线程命名、线程优先级设置等。
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class DefaultMyThreadFactory implements MyThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public DefaultMyThreadFactory(String prefix) {
SecurityManager s = System.getSecurityManager();
group = (s != null)? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = prefix + "-pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
3. 适应不同模块需求
- 线程命名:在构造函数中传入模块相关的前缀,如
new DefaultMyThreadFactory("module1")
,这样创建的线程名就会带有模块标识,方便在日志和调试时区分不同模块的线程。 - 线程优先级:可以在工厂类中增加设置优先级的方法,或者在构造函数中传入优先级参数,不同模块根据自身业务需求设置不同优先级。例如,对于处理关键业务逻辑的模块,可以将线程优先级设置为
Thread.MAX_PRIORITY
,而对于一些辅助性的模块,如日志记录模块,可以设置为较低优先级Thread.MIN_PRIORITY
。
4. 资源合理利用和性能优化
- 线程池大小配置:每个模块根据自身负载和资源需求,合理配置线程池大小。对于 I/O 密集型模块,可以设置较大的线程池大小,因为线程在等待 I/O 操作时会释放 CPU 资源;而对于 CPU 密集型模块,则应设置较小的线程池大小,避免过多线程竞争 CPU 资源。
- 资源监控与动态调整:通过使用 JMX(Java Management Extensions)等工具,监控每个线程池的运行状态,如线程活跃数、任务队列长度等。根据监控数据,动态调整线程池大小,确保资源的合理利用。例如,当任务队列长度持续增长时,可以适当增加线程池大小;当线程活跃数长时间较低时,可以适当减少线程池大小。
- 避免线程上下文切换开销:尽量减少线程的创建和销毁次数,通过线程池复用线程。同时,合理分配任务到不同线程池,避免任务在不同线程池之间频繁切换,降低上下文切换开销。
5. 示例代码(使用线程池结合线程工厂)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
MyThreadFactory factory = new DefaultMyThreadFactory("example");
ExecutorService executorService = new ThreadPoolExecutor(
5,
10,
10L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
factory
);
for (int i = 0; i < 20; i++) {
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName() + " is running.");
});
}
executorService.shutdown();
}
}
通过以上设计,能够实现一个通用的线程工厂,满足不同模块的需求,并确保系统整体的资源合理利用和性能优化。