目录
🍉单例模式分为饿汉模式和懒汉模式
🥝饿汉模式
所谓饿汉就是指非常饿,然后就是不管你new没new对象出来,他在背地里保留了一份,也只有一份的意思
java
class Singleton{
private static Singleton instance=new Singleton();
public static Singleton getInstance(){
return instance;
}
private Singleton(){}
}
public class Thread18 {
public static void main(String[] args) {
Singleton singleton1=Singleton.getInstance();
Singleton singleton2=Singleton.getInstance();
System.out.println(singleton1.equals(singleton2));
}
}
🥝懒汉模式
懒汉顾名思义就是非常懒,平常没有,只有你需要对象的时候,才new一个对象,也有且只有一份
java
class SingletonLazy{
private static SingletonLazy instance=null;
public static SingletonLazy getInstance(){
if(instance==null){
instance=new SingletonLazy();
}
return instance;
}
private SingletonLazy(){}
}
public class Thread19 {
public static void main(String[] args) {
SingletonLazy s1=SingletonLazy.getInstance();
SingletonLazy s2=SingletonLazy.getInstance();
System.out.println(s1.equals(s2));
}
}
然后在多线程情况下,饿汉模式由于提前准备了一份,且只涉及到读操作,所以它是线程安全的,而懒汉模式由于有写操作,所以会有线程不安全的情况
如下

如果是这样执行的话,线程1和线程2的instance对象就会不一样,也就是有两份对象,不满足我们单例模式下·只创建一份对象的初衷!
所以我们需要用好锁synchronized,具体如下

可是这样的话,我们知道非必要情况下,不要加锁,像这种情况,我们这样下,这样加锁,反而会影响到程序的效率,那怎么加锁呢,如下

这样即使是多线程情况下也是可以通过的,但我们忽略了一个问题就是instance=new SingletonLazy这样的操作没问题,但编译器会对其优化,也就是instance=new SingletonLazy背地里其实干了3件事,
1.申请空间
2.对内存进行优化
3.把内存地址赋值给引用
这33,编译器会优化顺序,啥都有可能,所以我们为了避开这种指令重排序的问题,就需要在对象这个玩意上,加个volitale关键字,也就是保证这3条指令是一条指令,也就是保证了原子性,如下

🍉阻塞队列
阻塞队列有两个关键作用
1是线程安全,它的各种方法用到了锁,不一定是synchronized
2是带有阻塞效果
java
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Thread20 {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> queue=new ArrayBlockingQueue<>(4);
queue.put("11");//入队列
queue.take();//出队列
}
}
阻塞队列一定意义上是一种生产者消费模型
这种模型
有降低锁冲突,解耦合,削峰填谷的优点,
也有通信效率降低,增加系统架构的复杂程度,提高了运维成本的缺点 !
完结