java对象,直接new,用静态变量返回static块中new好的对象,用synchronized返回静态变量,三者区别详解

举三个例子说明一下:第一个例子publicclassQueryCouponAmountDao{publicQueryCouponAmountDao(){}publicvo... 举三个例子说明一下:
第一个例子
public class QueryCouponAmountDao {

public QueryCouponAmountDao() {
}

public void run(){}
}

public class QueryCouponAmountService {

public QueryCouponAmountService() {
}

public void process(){
QueryCouponAmountDao query=new QueryCouponAmountDao();
query.run();
}
}

第二个例子
public class QueryCouponAmountDao {

private QueryCouponAmountDao() {
}

public static QueryCouponAmountDao instance;

static {
instance = new QueryCouponAmountDao();
}

public void run(){}
}

public class QueryCouponAmountService {

private QueryCouponAmountService() {
}

public static QueryCouponAmountService instance;

static {
instance = new QueryCouponAmountService();
}

public void process(){
QueryCouponAmountDao query=QueryCouponAmountDao.instance;
query.run();
}
}

第三个例子
public class QueryCouponAmountDao {

private QueryCouponAmountDao() {
}

private static QueryCouponAmountDao instance;

public synchronized static QueryCouponAmountDao getIntance() {
if (null == instance) {
instance = new QueryCouponAmountDao();
}
return instance;
}

public void run(){}
}

public class QueryCouponAmountService {

private QueryCouponAmountService() {
}

private static QueryCouponAmountService instance;

public synchronized static QueryCouponAmountService getIntance() {
if (null == instance) {
instance = new QueryCouponAmountService();
}
return instance;
}

public void process(){
QueryCouponAmountDao query=QueryCouponAmountDao.getIntance();
query.run();
}
}
类实例的方式当然都懂的,怪我说的不仔细,我是想问,这几种实现方式,在实际使用中的区别,比如我一口气取100w个实例,在三者情况下jvm处理的时所花费的时间和空间的比较,当然我知道,100W次new和一个static变量得100W次,空间上肯定是不一样的,但是其他方面呢?还有多线程环境下,又是怎么玩的?另外,new是每次都是取一个新的没什么疑问,如果是第二种情况,每次都是取类加载时的那一个静态实例对象,那这个类中的实例变量,静态变量不是都是共享的了,也就是说如果我第一次取这个类,改变了其中的实例变量和静态变量,那么我第二次再取这个静态实例对象象的时候,不是能够读取到前一个的改动了么?这样跟new出来的初始化时不一样的。第二和第三种情况在多线程环境下除了一个直接得对象,一个加锁得对象,当然实例的时间也有区别的,除了这些还有什么其他区别?@青衣秀士

上述问题自己有些明白,但是也有些说不清楚,望高手指导
展开
 我来答
栾喆B1
推荐于2017-11-26 · TA获得超过200个赞
知道小有建树答主
回答量:53
采纳率:0%
帮助的人:77.1万
展开全部
首先,不管哪种方式,都是通过new进行实例化,三种方式的不同在于,每次调用使用的dao对象是否相同。

1)直接new:每次调用都需要实例化;
2)静态变量,在这个类被加载时已经实例化好,调用process方法时直接使用;
3)带synchronized的getter,与第2个基本一致,只是实例化阶段在第一次使用时,简称为lazy init,懒加载。

在类的实例数来看,第一种为多个,后两种为一个。

==================
“比如我一口气取100w个实例,在三者情况下jvm处理的时所花费的时间和空间的比较,当然我知道,100W次new和一个static变量得100W次,空间上肯定是不一样的,但是其他方面呢?还有多线程环境下,又是怎么玩的?另外,new是每次都是取一个新的没什么疑问,如果是第二种情况,每次都是取类加载时的那一个静态实例对象,那这个类中的实例变量,静态变量不是都是共享的了,也就是说如果我第一次取这个类,改变了其中的实例变量和静态变量,那么我第二次再取这个静态实例对象象的时候,不是能够读取到前一个的改动了么?这样跟new出来的初始化时不一样的。第二和第三种情况在多线程环境下除了一个直接得对象,一个加锁得对象,当然实例的时间也有区别的,除了这些还有什么其他区别?”

jvm处理时的时间和空间比较,空间上来看,每次调用都new,频繁调用后必然会触发GC,而调用GC进行回收时一般都会暂停工作线程,如果回收时间较长则会造成卡顿现象。从时间上来看,每次new时都需要去分配堆内存,而static共享的只需要取出句柄即可。

static在这个比较中的主要劣势在于:1)资源共享,多线程场景注意保护;2)资源常驻内存,很难被回收。

多线程方面,不能简单从实例数量上来看,而是需要看具体场景是否存在着资源竞争。
smart灬雪
2014-02-13 · 超过12用户采纳过TA的回答
知道答主
回答量:74
采纳率:0%
帮助的人:32.7万
展开全部
调用楼上的话,我做部分补充。
首先,不管哪种方式,都是通过new进行实例化,三种方式的不同在于,每次调用使用的dao对象是否相同。

1)直接new:每次调用都需要实例化;
2)静态变量,在这个类被加载时已经实例化好,调用process方法时直接使用;
3)带synchronized的getter,与第2个基本一致,只是实例化阶段在第一次使用时,简称为lazy init,懒加载。在类的实例数来看,第一种为多个,后两种为一个。
补充:后两种属于一种开发模式叫单例模式,就是说实例只有一个。前者叫饿汉模式,即加载就实例化一个静态实例。后者是懒汉模式,即第一次使用的时候创建一个静态实例。加锁是为了线程安全,保证实例有且只有一个。
更多追问追答
追问
麻烦看下补充提问呵,qqq
追答
请搞明白。第一种想要几个实例,你自己new几个。后两种都是单例,该类的实例只有一个,何来100W个实例一说?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
不羁一世
2014-02-13 · 超过36用户采纳过TA的回答
知道小有建树答主
回答量:83
采纳率:0%
帮助的人:76.1万
展开全部
1)直接new:每次开辟新的内存空间,生成一个新对象,对象里的属性全部为默认值了。可以人工清除灵活使用内存空间。
2)静态变量:在程序启动后一直存在内存中,适用于常量的使用和初始化内容。
3)带synchronized:简单的说就是单例模式,可以自己去查查。在项目设计时用的比较多。长用于控制其他对象。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式