static修饰的成员叫“类成员”-》“类属性/类方法”
不加static修饰的成员,叫做“实例成员”-》“实例属性/实例方法”
一个Java程序中,一个类对象只存在一份(JVM保证的),进一步的也就保证了类的static成员也是只有一份的
类对象:就是.class文件,被JVM加载到内存后,表现出的模样。类对象里就有.class文件中的一切信息,包括类名是啥,类里有哪些属性,每个属性叫啥名字,每个属性是啥类型,属性是public、private……
类:相当于实例的模板,基于模板可以创建出很多的对象来
对象:就是实例
单例模式的两种实现:
饿汉模式:比较着急的去进行创建实例
懒汉模式:不太着急的去创建实例,只是在用的时候,才真正创建
关于多线程的案例:
案例一、实现一个线程安全的单例模式:要求代码中的某个类,只能有一个实例,不能有多个
通过Singleton这个类来实现单例模式,保证Singleton这个类只有唯一实例
(1)饿汉模式:
//实现单例模式-饿汉模式 class Singleton{ //1、使用static创建一个实例,并且立即进行实例化 //这个instance对应的实例,就是该类的唯一实例 private static Singleton instance=new Singleton();//立即初始化实例,所以叫饿汉模式 //被static修饰的类成员只有一份 //2、为了防止程序员在其他地方不小心new这个Singleton,就可以把构造方法设为private private Singleton(){} //3、提供一个方法,让外面能够拿到唯一实例 public static Singleton getInstance(){ return instance; } } public class Demo3 { public static void main(String[] args) { Singleton singleton=Singleton.getInstance(); } }饿汉模式中getInstance仅仅是读取了变量的内容,如果多个线程只是读同一个变量,不修改,此时仍然是线程安全的~
(2)懒汉模式:
//实现单例模式-懒汉模式 class Singleton2{ //1、就不是立即就初始化实例 private static Singleton2 instance=null; //2、把构造方法设为peivate private Singleton2(){} //3、提供一个方法来获取到上述单例的实例 //只有当真正需要用到这个实例的时候,才会真正去创建这个实例-》懒汉模式 public static Singleton2 getInstance(){ if(instance==null){ instance=new Singleton2(); } return instance; } } public class Demo4 { public static void main(String[] args) { Singleton2 instance=Singleton2.getInstance(); } }懒汉模式中,既包含了读,又包含了修改,而且这里的读和修改还是分成两个步骤的(不是原子的),存在线程安全问题~
改进方案:进行加锁
但是事实上,线程不安全问题只发生在instance初始化之前,也就是说初始化之后,已经线程安全了,可是按照上述的加锁方式,每次调用getInstance都会进行加锁,会存在已经线程安全了,但是还因为加锁存在大量的锁竞争(存在的问题)
改进方案:让getInstance初始化之前进行加锁,初始化之后就不再加锁(在加锁之前加上一层判断条件)
但是还是会有问题,当刚开始就有很多线程都去调用getInstance时,就会造成大量的读instance内存的操作,可能会让编译器把这个读内存操作优化成读寄存器操作,也就是出现内存可见性问题,可能会引起第一个if判定失效,但是对于第二个if判定影响不大(因为synchronized可以保证内存可见性),由于可能会引起第一个if判定失效,会导致不该加锁的给加锁了,但是不会引起第二层if的误判(不至于说创建多个实例)
改进方案:给instance加上volatile
因此要想利用懒汉模式创建一个线程安全的单例模式需要注意:
1、正确的位置加锁:为了保证线程安全
2、双重if判定:第一层if是为了避免不必要的加锁,初始化之后就不用加
本文详细介绍了Java中多线程的几个经典案例,包括饿汉模式和懒汉模式实现的线程安全单例模式,阻塞队列在生产者消费者模型中的应用,以及定时器的实现和线程池的工作原理。通过这些案例,深入理解Java多线程的机制和最佳实践。



最低0.47元/天 解锁文章
1748

被折叠的 条评论
为什么被折叠?



