Java设计模式之一 —— 单态模式
来源:互联网 发布:中船重工集团718知乎 编辑:程序博客网 时间:2024/06/10 00:26
1.问题的提出
假设我们想要向数据库中的某个表中insert多条记录,insert操作可能是由多个线程并发来完成,那么此数据表中的主键ID是通过我们写的一个程序来完成数字的自增。我们来写一个类,用来取得下一个主键ID的值,并在insert操作中插入此主键ID。代码如下:
{
//取得下一次插入数据表中的主键ID
public static Integer getNextTableId()
{
//取得数据表中当前主键ID
//代码略
//返回下一此插入数据库表中的主键ID
return tableId++;
}
}
我们再写5个线程来模拟一下主键ID生成器,代码如下:
{
private boolean active;
private long millis;
private String myThreadId;
public ThreadSingleton(long ms, String threadId)
{
this.millis = ms;
this.active = true;
this.myThreadId = threadId;
}
public void run()
{
while (this.active)
{
Singleton.printOrder();
try
{
super.sleep(this.millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public class Client
{
public static void main(String[] args) throws InterruptedException
{
long delay = 100;
ThreadSingleton mt1 = new ThreadSingleton(delay,"001");
mt1.start();
ThreadSingleton mt2 = new ThreadSingleton(delay,"002");
mt2.start();
ThreadSingleton mt3 = new ThreadSingleton(delay,"003");
mt3.start();
ThreadSingleton mt4 = new ThreadSingleton(delay,"004");
mt4.start();
ThreadSingleton mt5 = new ThreadSingleton(delay,"005");
mt5.start();
}
}
于是问题产生了,在开发级测试中,我们通过多线程并发取得需要插入的主键ID,并向此数据表中insert内容,几乎不会有问题,然而在企业级测试中,例如1000个人或更多的人同时对此数据表进行insert操作的时候,就会出现主键ID重复错误和顺序颠倒。模拟运行结果如下:
原因就是我们在通过 getNextTableId()方法取得下一次需要插入的主键ID时,由于1000乃至更多的线程同时并发, getNextTableId()方法取得TableID可能会出现相同的情况,也就是说可能存在某一个时刻,两个进程同时取得的TableID为100,那么此方法返回的结果同时为101,那么我们向数据库中插入的两条数据的主键ID同时为101,结果出错。
2.解决问题
我们想解决上面的问题,首先需要一个对象或方法,无论有多少个线程去访问,在同一个时刻,只能有一个对象或方法被使用。那么在java里面我们可以采用synchronized关键字来保证一个类只允许存在一个实例,并提供一个可以访问它的全局访问点。
3.类图设计
4.代码编写
public class Singleton
{
//定义一个Singleton类的对象
private static Singleton instance = null;
//进行主键ID自增模拟
private static int order = 1;
//定义一个生成唯一一个Singleton对象的方法
public static synchronized Singleton getInstance()
{
//如果instance为空
if (instance == null)
{
//new一个Singleton对象,保证只生成一个instance对象
instance = new Singleton();
}
//返回instance对象
return instance;
}
//模拟主键自增的测试方法
public static synchronized void printOrder()
{
//向控制台输出主键ID
System.out.println(order++);
}
}
由于给getInstance()方法和 printOrder()方法加上了synchronized关键字,那么在多线程访问它们时,在同一时刻只会生成同一个Singleton实例。程序的运行结果如下:
运行结果正确,不在出现ID重复和顺序颠倒的错误。
5.总结——趣味见解
我们很多朋友到一家比较小的餐馆去喝酒,这家餐馆只有一个厨师。我们点了很多很多的菜,但是无论我们点多少,只能通过这一个厨师来掌勺。虽然有点慢,但是也没办法。
- Java设计模式之一 —— 单态模式
- Java设计模式之一——单例模式
- java设计模式之一“单例模式”
- Java设计模式之一:单例模式
- javascript设计模式之一——单例模式
- java设计模式——单态设计模式
- Java 设计模式—单例模式
- java设计模式—单例模式
- java设计模式—单例模式
- java设计模式—单例模式
- Java设计模式—单例模式
- Java设计模式—单例模式
- Java设计模式之一 单例设计模式
- Java设计模式—单态模式(Singleton)
- java设计模式学习系列之一:单例模式(Singleton)
- java设计模式学习系列之一:单例模式(Singleton)
- JAVA设计模式之一(单例模式)
- Java常用GoF设计模式之一单例模式
- 《蚁族——大学毕业生聚居村实录》
- this&super的意义和用法
- 数组和字符串操作(C#) 1、从字符串中删除指定字符
- RIBCHECKIBIN
- ARM IMPORT |Image$$RO$$Limit| 的含义
- Java设计模式之一 —— 单态模式
- ubuntu下netbeans字体调整
- How to configure FTP Adapter based on IIS7.5 on a WINDOWS 2008 R2 OS
- VirtualBox:宿主机windows与虚拟机Ubuntu资源共享
- Corner Detection Using cvGoodFeaturesToTrack
- 前端优化之-设置较长的expires
- 【转】不要给技术人员做绩效 - 潘燕辉的专栏 - CSDN博客
- 列表划过效果,和点击效果!!!
- The first blog on CSDN, just like sofa~~