今天领导问了个问题说单例模式中,对象的变量是否是线程安全的。起初都不太确定,后来本着装的目的,试了一下,结果是否定的。在多线程环境下,对象的成员变量是不安全的。
package com.zhuyang.test;
public class Singleton {
private static final Singleton singleton;
//variable will be updated in muti-thread
private int count;
static {
singleton = new Singleton();
}
public static synchronized Singleton getInstance() {
return singleton;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
上面的代码是一段标准的单例模式。 其中有个成员变量count.他的值,会再多线程环境下不断修改。
package com.zhuyang.test;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadTest t1=new ThreadTest(1111);
ThreadTest t2=new ThreadTest(2222);
ThreadTest t3=new ThreadTest(3333);
ThreadTest t4=new ThreadTest(4444);
ThreadTest t5=new ThreadTest(5555);
ThreadTest t6=new ThreadTest(6666);
ThreadTest t7=new ThreadTest(7777);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
}
}
class ThreadTest extends Thread {
private int threadID;
public ThreadTest(int threadID) {
this.threadID = threadID;
}
@Override
public void run() {
Singleton singleton = Singleton.getInstance();
singleton.setCount(threadID);
System.out.println(this.getName()+"is updating count value is="+this.getThreadID()+", count value of singleton is="+singleton.getCount());
}
public int getThreadID() {
return threadID;
}
public void setThreadID(int threadID) {
this.threadID = threadID;
}
}
运行上面的代码结果:
Thread-0is updating count value is=1111, count value of singleton is=4444
Thread-4is updating count value is=5555, count value of singleton is=4444
Thread-5is updating count value is=6666, count value of singleton is=4444
Thread-2is updating count value is=3333, count value of singleton is=4444
Thread-6is updating count value is=7777, count value of singleton is=4444
Thread-3is updating count value is=4444, count value of singleton is=4444
Thread-1is updating count value is=2222, count value of singleton is=4444
说明,多线程中,单例模式并非线程安全,即便是加上了synchronized关键字。
那么如何做到线程安全呢?做法就是把对象给synchronized掉,看代码。
package com.zhuyang.test;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadTest t1=new ThreadTest(1111);
ThreadTest t2=new ThreadTest(2222);
ThreadTest t3=new ThreadTest(3333);
ThreadTest t4=new ThreadTest(4444);
ThreadTest t5=new ThreadTest(5555);
ThreadTest t6=new ThreadTest(6666);
ThreadTest t7=new ThreadTest(7777);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
}
}
class ThreadTest extends Thread {
private int threadID;
public ThreadTest(int threadID) {
this.threadID = threadID;
}
@Override
public void run() {
Singleton singleton = Singleton.getInstance();
synchronized (singleton) {
singleton.setCount(threadID);
System.out.println(this.getName()+"is updating count value is="+this.getThreadID()+", count value of singleton is="+singleton.getCount());
}
}
public int getThreadID() {
return threadID;
}
public void setThreadID(int threadID) {
this.threadID = threadID;
}
}
结果:
Thread-0is updating count value is=1111, count value of singleton is=1111
Thread-1is updating count value is=2222, count value of singleton is=2222
Thread-2is updating count value is=3333, count value of singleton is=3333
Thread-3is updating count value is=4444, count value of singleton is=4444
Thread-4is updating count value is=5555, count value of singleton is=5555
Thread-6is updating count value is=7777, count value of singleton is=7777
Thread-5is updating count value is=6666, count value of singleton is=6666
分享到:
相关推荐
Java中懒汉单例设计模式线程安全测试,单例设计模式的测试
线程安全的单例模式 线程安全的单例模式 线程安全的单例模式
C++11实现线程安全的单例代码和测试代码,包含singleton.h,main.cpp,希望帮助到大家。
NULL 博文链接:https://javawl.iteye.com/blog/1831804
使用"懒汉模式"与"饿汉模式"实现c++的单例模式,并且确保了单例模式的第一次实例化的线程安全,以及程序结束时,单例对象的资源收回,以防内存资源的泄漏
单例模式三种线程安全的表达方式,其中枚举方式的单例是最安全的
主要介绍了Java 单例模式线程安全问题的相关资料,希望通过本文大家能了解掌握单例模式中线程安全的使用方法,需要的朋友可以参考下
深入浅出:讲解单例模式,多线程安全和并发访问问题.让你轻松应对面试
1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法...
主要介绍了python实现线程安全的单例模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
3.4懒汉式(线程安全,使用同步方法) 9 3.5双重检查实现单例模式 10 3.6使用静态内部类实现单例模式 12 3.7使用枚举类实现单例模式 13 4.单例模式怎么用才合理? 14 4.1测试 14 4.2无边界 15 5.设计模式学习总结: ...
下面小编就为大家带来一篇从C++单例模式到线程安全详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
保证一个类只有一个实例,并提供一个访问它的全局访问点,使得系统中只有唯一的一个对象实例,具有线程安全,多线程测试通过。 1.打开日志并创建日志文件夹 默认为程序启动路径 2.清理日志文件下日志数量 默认保留90...
双重校验锁模式结合了懒汉模式和饿汉模式的优点,既实现了延迟加载,又保证了线程安全。你可以根据需求选择合适的单例模式实现方式。
该资源是多线程并发下的单例模式-源码,几乎包含了所有方式实现的单例模式,并且能够确保在多线程并发下的线程安全性。 读者可结合本人博客 http://blog.csdn.net/cselmu9?viewmode=list 中的《线程并发之单例模式...
Java多线程--解决单例模式中的懒汉式的线程安全问题
1、掌握单例模式的应用场景。 2、掌握 IDEA 环境下的多...3、掌握保证线程安全的单例模式策略。 4、掌握反射暴力攻击单例解决方案及原理分析。 5、序列化破坏单例的原理及解决方案。 6、掌握常见的单例模式写法。
单例模式 Singleton 单例模式线程安全问题和拓展
懒汉式—线程安全:加上synchronize之类保证线程安全的基础上的懒汉模式,相对性能很低,大部分时间并不需要同步 饿汉方式。指全局的单例实例在类装载时构建。 [2] 双检锁式。在懒汉式基础上利用synchronize关键字和...