面试题答案
一键面试匿名内部类在多线程中实现Runnable接口的应用方式
在多线程编程中,使用匿名内部类实现Runnable
接口非常简洁。示例代码如下:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 线程执行的具体逻辑
System.out.println("This is a thread running.");
}
});
thread.start();
上述代码中,通过new Runnable()
创建了一个实现Runnable
接口的匿名内部类实例,并重写了run
方法,该方法内的代码就是线程要执行的逻辑。
背后原理分析
- 内存分配:
- 当创建匿名内部类实例时,会在堆内存中为其分配空间。它会持有外部类(如果在非静态方法中创建)的引用,这意味着如果外部类中有大量成员变量,会间接增加匿名内部类实例的内存占用。
- 例如,在一个包含很多成员变量的类
OuterClass
的方法中创建匿名内部类new Runnable() {... }
,匿名内部类实例除了自身代码和数据占用的内存外,还会包含对OuterClass
实例的引用,从而间接引用OuterClass
中的所有成员变量。
- 生命周期:
- 匿名内部类实例的生命周期与它所依附的对象紧密相关。如果在方法中创建,当方法执行完毕,若没有其他对象持有对匿名内部类实例的引用,它就符合垃圾回收的条件。
- 但如果线程正在运行,由于线程持有对匿名内部类实例(实现了
Runnable
接口)的引用,此时匿名内部类实例不会被垃圾回收,直到线程执行完毕或者不再持有对该实例的引用。例如,若将上述创建的thread
对象设置为null
,且线程执行完毕,那么匿名内部类实例就可能被垃圾回收。
在其他编程语言如Python中,虽然没有严格意义上的匿名内部类概念,但可以通过lambda
表达式实现类似简洁的功能。例如在Python中使用threading.Thread
创建线程:
import threading
def print_message():
print("This is a thread running.")
thread = threading.Thread(target=lambda: print_message())
thread.start()
这里lambda
表达式起到了类似匿名内部类实现Runnable
接口的简洁功能,在内存和生命周期方面,lambda
表达式定义的函数对象同样在堆内存中分配空间,其生命周期也与引用它的对象(如这里的Thread
实例)相关。