论坛首页 Java企业应用论坛

单例模式结合观察者模式

浏览 9714 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-12-23   最后修改:2009-12-23
起因:多线程对数据库写操作
办法:让多线程先把数据写到一个公共的arraylist中,等这个list足够大的时候,单开一个线程进行写操作。
方案:
      首先,将这个arraylist使用单例模式思想,这样就可以让多线程都用它,并且写一起。
      然后,用观察者观察这个arraylist的长度,如果到了指定长度,就进行写操作,同时清空这个arraylist,方便多线程们继续使用。
      结果,实现了!!


-----
感谢对此方案提出过宝贵意见的 姜同学,小强同学,大师同学~~~hoho~~排名不分先后~~O(∩_∩)O哈哈~

demo: 让一个循环让单例的arraylist写数字...每当arraylist长度到5的时候,打印arraylist,并且置空。

代码如下:
Singleton.java    单例的类

package testArray;


import java.util.ArrayList;
import java.util.Observable;

public class Singleton extends Observable{
	
	private ArrayList<String> arrayList=new ArrayList<String>();
	
	private static Singleton singleton=null;
	
	/**
	 * 避免被继承
	 */
	private Singleton(){
		
	}
	
	/**
	 * 产生单例
	 * @return
	 */
	public static Singleton getInstance(){
		if(singleton==null){
			singleton=new Singleton();
		}
		return singleton;
	}

	/**
	 * 只要能置空arraylist就行.
	 */
	public static void clearInstance(){
		singleton.arrayList.clear();
		
	}
	public  void putElement(String str){
		arrayList.add(str);
		if(arrayList.size()>5){
			setChanged();  //触发观察者模式
			notifyObservers(arrayList);
		}
	}
	
	

}



DataOperation.java  操作类
package testArray;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

public class DataOperation implements Observer {

	private ArrayList<String> arrayList=null;
	
	public void update(Observable o, Object arg) {
		if(arg instanceof ArrayList){
			arrayList=(ArrayList)arg;
			for(String s : arrayList){
				System.out.println(s);
			}
			System.out.println("*********************************");
			Singleton.clearInstance();//想在这里让那个单例的list置空
		}
		
	}

}



测试类 Test.java
package testArray;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Singleton singleton=Singleton.getInstance();
		singleton.addObserver(new DataOperation());
		int i=0;
		while(i<12){
			singleton.putElement(i+":ele");
			i++;
		}
		
		
	}

}



结果:
0:ele
1:ele
2:ele
3:ele
4:ele
5:ele
*********************************
6:ele
7:ele
8:ele
9:ele
10:ele
11:ele
*********************************

   发表时间:2009-12-23  
个人觉得有这样几个问题:
1.getInstance()方法层中访问冲突,应该同步,加上synchronized
2.如果putElement()函数没程序区调用或很长时间才调用,那里面现有的数据岂不是一直不会写到数据库
0 请登录后投票
   发表时间:2009-12-23  
hxpterry 写道
个人觉得有这样几个问题:
1.getInstance()方法层中访问冲突,应该同步,加上synchronized
2.如果putElement()函数没程序区调用或很长时间才调用,那里面现有的数据岂不是一直不会写到数据库

确实有上述问题

1.访问冲突..这个还没想清楚..=.= 我测试测试
2.这个确实是有的。主要我的系统中要存的这些都是用户信息..所以..少那么几个..或者延迟了..都影响不大..只要迟早能进库就行..不是那种安全性和实时性很高的.

0 请登录后投票
   发表时间:2009-12-23  
大概看了一下,在创建单例的代码中没有实现同步,并发情况下会有问题。
0 请登录后投票
   发表时间:2009-12-23   最后修改:2009-12-23
楼主实现的不就是一个缓存么,应该用HashTable好些。

也可以用时间线程定期数据入库。

------------------------------

有一个我不明白,为什么要开单例。为了什么?

==============================

你用单例就是为了让这几个线程共享内存啊,你传全局参不就行了吗。

如果你的意思是,这几个线程不是运行在一个容器里(比如一个servlet,一个main方法),让他们共享内存的话,结果是:他们是共享不到资源的。单例只是在一个进程中单例,只能这一个进程中的多个线程才能共享资源的。
0 请登录后投票
   发表时间:2009-12-23  
lz,你这个不单单例这里会有线程问题
put和clean两个方法也有线程问题。

0 请登录后投票
   发表时间:2009-12-23  
应该用现有的成熟的缓存解决方案。。。
还有,为什么要单例?一个sync的全局变量不就完了?
0 请登录后投票
   发表时间:2009-12-23  
单线程下应该没什么问题,多线程的话明显就是生产者消费者模型了。。。
0 请登录后投票
   发表时间:2009-12-24  
其实就是一个BlockingQueue的事,这两个模式组合的生搬硬套了,还不解决需求
0 请登录后投票
   发表时间:2009-12-24  
(⊙o⊙)哦~原来可以有这么多解决方案..
谢谢大家~~

这个缓冲就是为了网页多并发的..
每一个用户打开页面后我都收集一些用户信息,通过ajax传到服务器.
然后放到这么一个缓冲里,再存入数据库.

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics