为什么JAVA匿名内部类接受所在方法的局部变量时要求为final?
匿名内部类使用所在方法传入的参数为什么要求使用final类型呢?
我们仔细研究下stack中随着方法调用的变化。
每个执行中的方法在内存stack中有一个专用的frame,ebp指向开始处,esp指向正在执行处。
方法的局部变量时直接存储在frame中的,而全局变量、final是存储在heap中。
当在这个frame中调用其他方法时(包括自己或其他对象的方法),会压栈,push ebp;生成新的frame。
要把前一个frame中的局部变量传递给新frame,一般使用的是相对位置。例如在新frame中使用上一个frame的变量会使用ebp-4,ebp-8的地址代替。
好了,在正常的调用过程中,都是一个frame,接着一个frame的,参数也是一个接一个传递的。
比如对象A,对象B,对象C,那么A调B,B调C,参数是A传到B,B传到C,可以很正常的通过相对位置找到这些参数。
你想想看,如果是使用匿名内部类,A中创建一个匿名类C,把参数传给他,这个时候并没有真正执行C的方法,你让C怎么记录这个参数地址?然后把这个匿名内部类放在B的方法中,B在调用C,调用过程没有变,A调B,B调C,但参数传递过程变了,A给C,跨了一个B的frame,由于C不知道B的frame有多长,所以它不可能通过相对位置找到A中的局部变量。
线程池模型的一般结构是什么样的?
一个主线程 ThreadManager负责管理ThreadPool
Threads每执行一次任务就会在ThreadPool中将自己的状态设置为可用(idle),并进入wait状态。
ThreadManager从ThreadPool寻找idle的thread,并传递执行数据(比如socket、filehandler等等),最后notify它。
线程是通过什么方式实现wait的?
还是通过锁的机制实现的。任何一个执行中的线程需要wait时,一般的程序代码中写:
this.wait
this.someobj.wait
在jvm中这是一种虚拟锁等待机制,他会虚拟出this、this.someobj对象正在被别人使用holding,当前线程无法获取这个对象而release掉自己holding的所有锁。
实际上this、this.someobj并没有被其他thread holding,因此当前线程必须进入wait状态(fat lock),深度睡眠,而不是thin lock、自旋lock状态,因为轻量级锁又会马上使当前线程running起来。进入深度睡眠后,必须通过notify notifyall等方式发送中断告知线程你的资源可用了,thread这才可以running起来。
关键词:虚拟锁、中断、
操作系统是什么?
操作系统是一个程序,它管理硬件资源,对上(应用程序)提供一个标准、简易的接口(系统调用)。
所有硬件已经是一个有机整体。每一个硬件工程师都会把自己的一块设计好,并通过接口与其他的硬件设备交互。
bios是内嵌到主板上芯片上的程序,他会检测所有的硬件,加载引导程序执行。
如果你不需要操作系统,你完全可以把你的程序写在booted中,或者写booted、写loader,让程序执行。你必须掌握很多底层的知识,汇编语言、cpu指令集、内存空间、对其他硬件设备的控
制(磁盘、显示器)。如果没一个程序员开发的程序都要把所有的硬件管理好后,才可以开始真正的业务逻辑,那我们现在的程序绝不会如此丰富,仅仅是解决网络通信这一点,就是一个浩
大的工程。
操作系统是计算机启动后由bios加载执行的第一个程序,他直接很硬件资源打交道,对上提供接口,使应用程序不必在为繁杂的硬件接口而烦恼。操作系统是软件工程的艺术品,其实它早已超过了梵高的自画像,它是计算机的灵魂,如果没有它,计算机仅仅是行尸走肉,在bios下只能缓慢的向前爬行。
操作系统解决了哪些具体的问题?
1 计算机是通过中断、中断程序、驱动程序来控制硬件的。
中断,硬件设备在接受外部请求时,会向中断控制器(可编程的芯片)发送中断信号,中断控制器再把这个信号发送给cpu,cpu在收到信号后,调用中断程序来处理它。
我们按下键盘后,键盘就会将像cpu发出中断信号,并把按键信息一并附上。
而最特殊的中断应属时钟中断,他会定时的想cpu发送中断,以便cpu停下进行调度。
驱动程序。要对所有的硬件进行控制是非常麻烦的,朝不同的端口发送复杂的信号,操作系统本身是可以提供不同的接口给硬件工程师来实现,并封装专属硬件的复杂性。
2 要实现多任务,以及为每一个任务虚拟一个独立的运行环境。
首先要虚拟出一个进程的概念,一个进程代表一个在运行中的程序,它占用cpu、内存,以及与硬件设备交互。
内核要定义一批数据结构存放进程信息,并且通过时钟中断来进行进程调度,以免资源被一个程序独占。
为了虚拟出一个独立的运行环境,对应用程序而言,他想用独立的内存空间,在32位的cpu架构体系中,他是4G大小。
内核通过分段进行安全控制,通过分页实现多独立进程空间,以及多个任务的数据同时存在于内存中。
3 在封装了复杂的硬件程序控制代码后,对上应用程序提供标准的、简易的接口。
4提供文件系统,文件系统是用户数据的存储管理方式。他是数据的读写存储协议。不同的硬件设备实现相同的接口。
5提供网络交互接口
6提供用户界面