EffectiveJava学习笔记32:并发(下)-慎用延迟初始化、不要依赖于线程调度器

1.慎用延迟初始化

1.1 什么是延迟初始化?

延迟初始化:指延迟到需要域的值的时候,才将它初始化的行为。

这是一种性能优化,可以提高性能,降低开销。不过延迟初始化是把双刃剑。它可能会破坏线程安全。

所以在大部分情况下,正常的初始化要优先于延迟初始化。

 

1.2 对静态域进行延迟初始化

 

对静态域使用延迟初始化,可以使用lazy initialization holder class模式。

简单来说就是静态内部类,属于单例模式的一种。

定义静态方法,引用外部类的静态成员域。当第一次调用时

public class InitMain {
    public static void main(String[] args){
        staticInit a= staticInit.getInstance();
    }
}
public class staticInit {
        staticInit() {
            System.out.println("构造函数");
        }

        //类级内部类,也就是静态的成员内部类,该内部类的实例与外部类的实例没有绑定关系,
        //而且只有调用的时候才会装载,从而实现了延迟加载
        private static class SingletonHolder{
            //静态初始化器,由JVM保证线程安全
            private static staticInit instance = new  staticInit();
        }

        public static staticInit getInstance() {
            System.out.println("沙丁鱼获取了实例");
            return SingletonHolder.instance;
        }
}

 

1.3 对实例域进行延迟初始化

对实例域使用延迟初始化,可以使用双重检查模式(double check idiom)。

这种模式需要两次检查域的值,所以叫双重检查。

第一次检查没有锁定,查看域是否初始化,第二次检查有锁定。

只有当第二次检查无初始化时,才会初始化。当初始化后,域就不会被锁定了,所以volatile修饰比较重要。

 

 

2.不要依赖于线程调度器

这一节是对线程使用的一些忠告。

2.1.不要依赖于线程调度器

线程调度器是什么?

线程调度器是一个操作系统服务,它负责为 Runnable 状态的线程分配 CPU 时间。所以注意了!,它是一个操作系统服务,所以它是很大可能不可移植的,因为操作系统很多电脑并不同。

所以线程不要依赖于线程调度器。

 

2.2 保持尽可能少的可运行线程数量

这一点其实和性能有关,尽可能少的线程数量可以提高性能。所以如果线程在做无意义的工作的话,就不应该运行。

这里提供的解决方法是FixedExecutor 线程池,限制线程数量。使用CountDownLatch进行实现。

 

2.3 线程优先级是java最不可移植的特征

如题目,线程优先级虽然可以改善线程性能,但是线程优先级之前也讲过,是和操作系统挂钩的。

之前关于优先级的笔记

https://blog.csdn.net/asdfghj253/article/details/104050967

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值