Static Initializers and Lazy Instantiation

本文对比了懒加载实例化和静态初始化两种模式的优缺点。静态初始化速度快且编程简便,但资源消耗固定;懒加载实例化虽有额外的管理开销,但在资源控制方面更具优势,特别是对于昂贵资源如数据库连接的管理。
Why use Lazy Instantiation when static initialization is more efficient? Well, there are pros and cons to both, and there is no firm answer.

The Singleton article gave one solution for implementing global variables, but it wasn't the only solution. Java does, in fact, have global variables of a sort, but they're called class variables. Here is an example:

[b]"The most important reason for using Lazy Instantiation is keeping resources under control. "[/b]
[list]
[*]Listing 1
[/list]
static MyObject object1 = new MyObject()

In Listing 1, the static keyword is used to indicate that this particular variable, namely object1, is a class variable rather than an instance variable. This means that there will be only one copy of the variable for the class rather than one for each instance of the class. The code segment in Listing 1 not only creates the variable, it also contains a static initializer that gives the object a value. This static initialization occurs automatically when the class containing the variable is first accessed.

Here, first accessed is defined to be the first time one of the following events occurs:

[b]An instance of the class is created via a constructor.
A static method that is defined in the class (not inherited) is called.
A static variable that is declared in the class (not inherited) is assigned or otherwise accessed. This does not include the static initializer, which occurs at compile time.[/b]

The process of Lazy Instantiation, on the other hand, doesn't automatically allocate variables. It enables the creation of objects to be put off until they are actually needed. Instead of being created when the program first starts, the creation of variables managed via Lazy Instantiation is deferred until they are actually required.

Which is better? Lets start off with some examples.

Here is an example of static initialization:
[list]
[*]Listing 2
[/list]
public class MyClass {
static MyObject object1 = new MyObject();
void doProcess() {
object1.process();
}
}

In Listing 2,object1 is created and its value is initialized when the class
MyClass is first accessed. After some period of time,object1 will be used via the
doProcess() method.
Here is a similar code segment making use of Lazy Instantiation.
[list]
[*]Listing 3
[/list]
public class MyClass {
MyObject object1;
void doProcess() {
If (object1 == null)
object1 = new MyObject();
object1.process();
}
}

The code in Listing 3 performs the same function as in Listing 2 except that the
object1 variable is being managed via Lazy Instantiation. When MyClass is created, nothing is done with object1 other than implicitly setting its reference to null. The doProcess() method makes use of object1 and checks to see if it exists before using it. If it does not exist, an instance is created and then used.

[b]Now back to the big question: Which is better?[/b]

Different Purposes
When it comes to speed, the static version wins. Static methods are quicker than normal ones, as there is no code execution overhead. Classes implementing Lazy Instantiation contain management code that needs to be executed whenever access to a variable is required. In Listing 3, overhead is incurred every time object 1 is accessed, because it first needs to be checked for a null value.

For ease of programming, static wins again. Only a single line of code is required to implement a variable with a static initializer. As mentioned above, Lazy Instantiation requires that an object be checked for a null value every time it is accessed. Also, multithreaded applications would require use of the double-checked locking pattern, which results in additional code. (See previous article on Singletons for more information on this.)

Okay, so there are several reasons for using a static initializer, as my readers have mentioned. However, there are several good reasons to use Lazy Instantiation instead.

The first reason for Lazy Instantiation concerns the initialization of the managed object's value. For a static initializer, the initial value is determined at compile time. When the developer puts to code the line that creates the object, he or she also determines what the initial value is going to be. While this is fine for many uses, there are times when it just isn't good enough. Lazy Instantiation, however, initializes the value of an object when the object is created. Since the object is being created at runtime, there is much more data available which can be used to calculate an appropriate initial value. One example of this would be the placing of a user name and id in a session variable.

Secondly, items that are static cannot be used to implement an interface. Interfaces in Java are powerful programming constructs that allow classes to inherit method definitions. Static objects suffer a loss of a great deal of programming power by not being able to implement interfaces.

The most important reason of all for using Lazy Instantiation, however, is that of keeping resources under control. Static objects are always created, whether they are needed or not. If the object is never used, then space is wasted holding the object and time is wasted creating it. Objects managed by Lazy Instantiation will only be created if they are needed and do not suffer these problems. This is especially important if the resources used are valuable, such as a database connection. Why tie up a database connection if it is never going to be used?

Also, since static objects are created during the initialization of a Java program, a lot of processing needs to be done before the program can actually begin. Software built with Lazy Instantiation defers the creation of objects and thus starts up a lot faster. This makes the Java program appear more agile and responsive, a definite bonus if you are trying to sell the software to a client.

Summary
The pros and cons of static initializers versus Lazy Instantiation must be weighed to determine which is best for a given use. Both are powerful, and both are examples of good programming, but they serve different purposes.
基于分布式模型预测控制的多个固定翼无人机一致性控制(Matlab代码实现)内容概要:本文围绕“基于分布式模型预测控制的多个固定翼无人机一致性控制”展开,采用Matlab代码实现相关算法,属于顶级EI期刊的复现研究成果。文中重点研究了分布式模型预测控制(DMPC)在多无人机系统中的一致性控制问题,通过构建固定翼无人机的动力学模型,结合分布式协同控制策略,实现多无人机在复杂环境下的轨迹一致性和稳定协同飞行。研究涵盖了控制算法设计、系统建模、优化求解及仿真验证全过程,并提供了完整的Matlab代码支持,便于读者复现实验结果。; 适合人群:具备自动控制、无人机系统或优化算法基础,从事科研或工程应用的研究生、科研人员及自动化、航空航天领域的研发工程师;熟悉Matlab编程和基本控制理论者更佳; 使用场景及目标:①用于多无人机协同控制系统的算法研究与仿真验证;②支撑科研论文复现、毕业设计或项目开发;③掌握分布式模型预测控制在实际系统中的应用方法,提升对多智能体协同控制的理解与实践能力; 阅读建议:建议结合提供的Matlab代码逐模块分析,重点关注DMPC算法的构建流程、约束处理方式及一致性协议的设计逻辑,同时可拓展学习文中提及的路径规划、编队控制等相关技术,以深化对无人机集群控制的整体认知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值