当前位置:网站首页>单例模式(singleton pattern)
单例模式(singleton pattern)
2022-08-02 14:22:00 【半度纳】
什么是单例?
在整个应用程序中,某个类的实例只有一个.
class T{}
class Test{
main: 获取到T的实例
demo: 获取到T的实例
}
单例的应用
Spring中的bean默认都是单例
Servlet也是单例的
计算机的任务管理窗口
如何实现?
单例
1.构造方法私有化
2.在成员变量位置声明引用
3.提供公有的static方法用于向外部提供实例
1.懒汉式单例 (lazySingleton) - 需要保证线程安全
public class Singleton {
//构造方法私有化
private Singleton(){}
//只声明,不初始化
private static Singleton singleton;
//提供公有的static的同步synchronized的方法向外提供实例
public synchronized static Singleton getInstance(){
if (singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
懒加载机制:什么时候用,什么是去拿/创建对象
2.饿汉式单例 - HungrySingleton 本身就是线程安全的
public class Singleton{
private Singleton(){}
private static Singleton single=new Singleton();
public static Singleton getInstance(){
return single;
}
}
Synchronized回顾
用法:
Synchronized可以实现同步效果,是通过锁机制来保证线程安全的
修饰方法,都是给调用方法的对象加锁
用法一:修饰方法
- 修饰实例方法,会给调用当前方法的对象加锁,从而保证线程安全
- 修饰static方法,会给类对象加锁,从而保证线程安全,
用法二:修饰代码块
语法:
synchronized(同步监视器对象){
同步代码块
}
同步监视器对象由程序员自己制定,可以是任意对象,包括this
建议修饰代码块,修饰代码块可以在保证线程安全的同时尽可能的提高并发执行效率.
buy(){
.....选衣服
synchronized(试衣间){
.....试衣服(按顺序来)
}
}
实例变量 实例方法 -- 都是通过实例来调用的
static变量 static方法 -- 都是通过类名来调用的
Synchronized应用场景
场景一:同步的
class T:
synchronized demo(){}
class Test:
main:
T t = new T();
Thread th1 = new Thread(){
run:t.demo(); }
Thread th2 = new Thread(){
run:t.demo(); }
th1.start();
th2.start();
场景二:异步的
class T:
synchronized demo(){}
test(){}
class Test:
main:
T t = new T();
T t1 = new T();
Thread th1 = new Thread(){
run: t.demo();}
Thread th2 = new Thread(){
run:t1.demo();
}
th1.start();
th2.start();
场景三:异步的
class T:
synchronized demo(){}
test(){}
class Test:
main:
T t = new T();
Thread th1 = new Thread(){
run:t.demo(); }
Thread th2 = new Thread(){
run:t.test(); }
th1.start();
th2.start();
场景四:同步的
class T:
synchronized demo(){}
synchronized test(){}
class Test:
main:
T t = new T();
Thread th1 = new Thread(){
run: t.demo(); }
Thread th2 = new Thread(){
run:t.test();
}
th1.start();
th2.start();
场景五:异步
class T:
synchronized demo(){}
synchronized test(){}
class Test:
main:
T t = new T();
T t1 = new T();
Thread th1 = new Thread(){
run:t.demo(); }
Thread th2 = new Thread(){
run:t1.test(); }
th1.start();
th2.start();
边栏推荐
猜你喜欢
随机推荐
【面经】被虐了之后,我翻烂了equals源码,总结如下
DOM —— 事件对象
[Fault Diagnosis] Weak Fault Diagnosis of Fan Bearing Based on PSO_VMD_MCKD Method
解决跨域的方法 --- Proxy
2022-0801 第六小组 瞒春 学习笔记
二、QT界面开发--新建C语言工程
CUDA programming based on Visual Studio 2015 (1): basic configuration
Filter 过滤器
2021年度总结——收获圆满的一年
Golang基础教程
一、QT界面开发 --QT安装
详解C语言中的位操作运算符可以怎么用?
Golang学习(三十五) go 连接redis
golang时间-时间戳的获取-转换-计算
为什么四个字节的float表示的范围比八个字节的long表示的范围要广
VsCode更新后,怎么使用使用快捷键同时生成多个元素
2021 annual summary - complete a year of harvest
为什么四个字节的float表示的范围比八个字节的long要广?
2022-07-21 第六小组 瞒春 学习笔记
Scala的基础语法(小试牛刀)