首先写个单例:
?
|
1
2
3
4
5
6
7
8
9
10
|
public class SingleDemo {
private static SingleDemo s = null;
private SingleDemo(){}
public static SingleDemo getInstance(){
if(s == null){
s = new SingleDemo();
}
return s;
}
}
|
写个测试类:
?
|
1
2
3
4
5
6
7
8
|
public class ThreadDemo3 {
public static void main(String[] args) {
SingleDemo s1 = SingleDemo.getInstance();
SingleDemo s2 = SingleDemo.getInstance();
System.out.println(s2 == s2);
}
}
|
运行结果一直都是true,说明单线程下是没问题的,下面写个多线程来访问单例
?
|
1
2
3
4
5
6
7
8
9
10
11
|
public class ThreadTest implements Runnable {
//存放单例对象,使用Set是为了不存放重复元素
public Set<SingleDemo> singles = new HashSet<SingleDemo>();
@Override
public void run() {
//获取单例
SingleDemo s = SingleDemo.getInstance();
//添加单例
singles.add(s);
}
}
|
使用多线程并发访问单例:
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ThreadDemo3 {
public static void main(String[] args) {
// SingleDemo s1 = SingleDemo.getInstance();
// SingleDemo s2 = SingleDemo.getInstance();
// System.out.println(s2 == s2);
ThreadTest t = new ThreadTest();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
System.out.println(t.singles);
}
}
|
运行结果如下:
[com.persagy.thread.SingleDemo@1bc4459, com.persagy.thread.SingleDemo@150bd4d]
或
[com.persagy.thread.SingleDemo@12b6651]
说明有线程并发访问安全问题,获取的不一定都是同一个实例
如何解决线程安全问题呢?
当然使用同步锁机制了啊
下面改进单例:
?
|
1
2
3
4
5
6
7
8
9
10
|
public class SingleDemo {
private static SingleDemo s = null;
private SingleDemo(){}
public static synchronized SingleDemo getInstance(){
if(s == null){
s = new SingleDemo();
}
return s;
}
}
|
加入同步函数后线程安全问题解决了
运行多次都是获取同一个实例,不会出现2个实例的情况了
[com.persagy.thread.SingleDemo@12b6651]
但是在多线程并发访问的情况下,每个线程每次获取实例都要判断下锁,效率比较低,为了提高效率,我加入了双重判断的方法,解决了效率的问题
代码如下:
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class SingleDemo {
private static SingleDemo s = null;
private SingleDemo(){}
public static SingleDemo getInstance(){
/*如果第一个线程获取到了单例的实例对象,
* 后面的线程再获取实例的时候不需要进入同步代码块中了*/
if(s == null){
//同步代码块用的锁是单例的字节码文件对象,且只能用这个锁
synchronized(SingleDemo.class){
if(s == null){
s = new SingleDemo();
}
}
}
return s;
}
}
|
用这种方式解决了懒汉式的线程安全问题,也提高了效率,但是在实际开发中还是用饿汉式的比较多,毕竟这个代码比较多,比较繁琐。
以上就是小编为大家带来的完美解决单例设计模式中懒汉式线程安全的问题全部内容了,希望大家多多支持快网idc~
相关文章
猜你喜欢
- 64M VPS建站:怎样选择合适的域名和SSL证书? 2025-06-10
- 64M VPS建站:怎样优化以提高网站加载速度? 2025-06-10
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
- ASP.NET自助建站系统的域名绑定与解析教程 2025-06-10
TA的动态
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
您的支持,是我们最大的动力!
热门文章
-
2025-05-25 82
-
2025-05-29 50
-
2025-05-29 39
-
2025-05-27 79
-
2025-05-29 101
热门评论

