vm的基本组成
1、虚拟机的组成
所谓java能实现跨平台,是因为在不同平台上运行不同的虚拟机决定的,因此java文件的执行不直接在操作系统上执行,而是通过jvm虚拟机执行,我们可以从这张图看到,jvm并没有直接与硬件打交道,而是与操作系统交互用以执行java程序。
2、jvm运行流程
3、jvm的内存区域
1、内存区域:
对于从事C或者C++的程序员来说,必须对每个对象的整个生命周期负责。但是对于java程序员来说,在jvm的自动内存管理机制下,不需要为每一个对象去写delete或者free代码,不容易出现内存泄漏或内存溢出的问题。但正因为java程序员将内存管理权力交给了内存管理机制,所以一旦出现内存泄露或者内存溢出的问题,在对jvm内存结构不清楚的情况下,排除错误将成为一顶非常复杂且困难的工作。
2、运行时数据区:
虚拟机栈、本地方法栈和程序计数器 ——>线程隔离的数据区
方法区和堆 ——->由所有线程共享的数据区
程序计数器不会发生内存泄漏问题。对现成来说是私有的。
设计模式
1、策略模式
定义:策略模式将可变的部分从程序中抽象出来分离成算法接口,在该接口下分别封装一系列算法实现。
优点:
- 使用了组合,而不是单单是继承,使用架构更灵活。(注:组合关系—>例如王者里的英雄和召唤技能就是组合关系)
- 富有弹性,可以较好的应对未来的变化。(开-闭原则)
- 更好的代码复用性。(相对于继承)
缺点:
增加了对象的数目(当每个接口都做成一个对象,对象数目是不是增多了)
2、单例模式
定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供。就是所有请求都用一个对象做处理,比如我们常用的service和dao层的对象通常都是单例的。
设计原则:单例模式的类只提供私有的构造函数,
- 类定义中含有一个该类的静态私有对象。
- 该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
优点:
- 实例控制,单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
- 灵活性,因为类控制了实例化进程,所以类可以灵活改变实例化过程。
缺点:
- 开销,虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
可能的开发混淆,使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象,要通过该对象的getInstance()方法获取这个唯一的事例。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
3、多例模式
定义:指每个请求用一个新的对象来处理,比如struts2中的action层。多例模式中的多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
特点:多例可以有多个实例,通过new创建。
- 多例类必须又能够自我创建并管理自己的实例,并且外界提供自己的实例。
- 构造方法私有化,类内部提供几个实例化对象,然后通过static方法获得。
总结:
- 在多线程中,对于单例模式,所有线程对该对象的引用都指向它的唯一一个实例;对于多例模式,所有线程都会创建该对象的实例。下面总结了多线程编程在这两种模式下的使用特点:
- 如果一个对象含有静态变量或者静态方法(且方法内部使用了静态变量),不管该对象是单例模式还是多例模式,都存在线程不安全的问题,需要使用synchronized同步锁。
- 单例模式下,如果对象含有公共成员变量,存在线程不安全。在调用对象的方法时,每个线程都会在自己的栈内存中开辟一段空间来复制并执行该方法,因此,如果该方法不涉及公共成员变量,就是线程安全的,否则就是线程不安全的。
- 多例模式下,如果没有静态属性,线程安全。
- springMVC,struts2中单例模式和多例模式的应用,以及存在的线程安全问题。
- struts2的action对象默认为多例模式,因为网页前端传来的请求参数都是不一样的,要保证存在action的对象属性中,因此必须设置成多例。
- SpringMVC的controller默认为单例模式,如果controller内没有成员属性,那么就是线程安全的。但是实际开发中,我们一般都会在controller内包含service、dao,因此要在controller前面加上@Scope(“prototype”),改成多例模式。
