只是一个简单的思路
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 适用于大数据量的导入操作
* @author qth
*
*/
public abstract class SingleThreadSaver {
private Map<String, Long> countHolder = null;
private List<String> errorMsgHolder = null;
private static final String COUNT_KEY_SUCCESS = "success";
private static final String COUNT_KEY_ERROR = "error";
private SingleThreadSaverPool pool = null;
public SingleThreadSaver() {
countHolder = new HashMap<String, Long>();
countHolder.put(COUNT_KEY_SUCCESS, 0L);
countHolder.put(COUNT_KEY_ERROR, 0L);
errorMsgHolder = new ArrayList<String>();
pool = SingleThreadSaverPool.getInstance();
}
public List<String> getErrorMsgList() {
List<String> ret = new ArrayList<String>();
ret.addAll(errorMsgHolder);
return ret;
}
protected synchronized void increaseSuccessCount() {
countHolder.put(COUNT_KEY_SUCCESS,
countHolder.get(COUNT_KEY_SUCCESS) + 1);
}
public long getSuccessCount() {
return countHolder.get(COUNT_KEY_SUCCESS);
}
protected synchronized void increaseErrorCount() {
countHolder.put(COUNT_KEY_ERROR,
countHolder.get(COUNT_KEY_ERROR) + 1);
}
public long getErrorCount() {
return countHolder.get(COUNT_KEY_ERROR);
}
protected void addErrorMsg(String msg) {
errorMsgHolder.add(msg);
}
public void saveInSingleThread() {
final Date now = new Date();
new Thread(new Runnable() {
@Override
public void run() {
try {
save();
} catch(Exception e) {
e.printStackTrace();
addErrorMsg(e.getMessage());
increaseErrorCount();
} finally {
try {
pool.releaseSaver(SingleThreadSaver.this);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
/**
* 单线程执行体
*/
protected abstract void save();
}
===========================================
package com.nssc.exam.common;
import java.util.HashMap;
import java.util.Map;
/**
* 利用线程池管理SingleThreadSaver, 每种Class的SingleThreadSaver同一时间中只允许运行5个
* @author qth
*
*/
public final class SingleThreadSaverPool {
private static SingleThreadSaverPool instance = null;
private static Map<Class<? extends SingleThreadSaver>, Map<SingleThreadSaver, Integer>> pool = null;
private static final int POOL_SIZE_DEFAULT = 5;
private static final Integer STATE_FREE = 0;
private static final Integer STATE_BUSY = 1;
private SingleThreadSaverPool() {
pool = new HashMap<Class<? extends SingleThreadSaver>,
Map<SingleThreadSaver,Integer>>();
}
public static SingleThreadSaverPool getInstance() {
if(instance == null) {
instance = new SingleThreadSaverPool();
}
return instance;
}
/**
* 取得一个空闲的 saver
* @param clazz
* @return
* @throws Exception
*/
public static <T extends SingleThreadSaver> T getSaver(
Class<? extends SingleThreadSaver> clazz)
throws Exception {
if(instance == null) {
instance = new SingleThreadSaverPool();
}
Map<SingleThreadSaver, Integer> subPool = pool.get(clazz);
if(subPool == null || subPool.isEmpty()) {
subPool = new HashMap<SingleThreadSaver, Integer>();
for(int i = 0; i < POOL_SIZE_DEFAULT; i++) {
SingleThreadSaver saverTmp = clazz.newInstance();
subPool.put(saverTmp, STATE_FREE);
}
pool.put(clazz, subPool);
}
for(Map.Entry<SingleThreadSaver, Integer> entry : subPool.entrySet()) {
SingleThreadSaver tmp = entry.getKey();
if(subPool.get(tmp) == STATE_FREE) {
subPool.put(tmp, STATE_BUSY);
return (T)tmp;
}
}
//now all 5 are busy
throw new IllegalStateException("No free saver available, please try later.");
}
/**
* 释放得到的saver
* @param <T>
* @param saver
*/
public static <T extends SingleThreadSaver> void releaseSaver(T saver)
throws Exception {
Map<SingleThreadSaver, Integer> subPool = pool.get(saver.getClass());
if(subPool == null || subPool.isEmpty()) {
throw new IllegalStateException("The saver passed is not get from pool!");
}
if(subPool.get(saver) == STATE_FREE) {
throw new IllegalStateException("Pool is NOT working properly!");
}
subPool.put(saver, STATE_FREE);
}
}
===========================================
项目实例:大量照片从文件系统导入数据库
===========================================
import java.io.File;
import java.util.Date;
import com.nssc.exam.common.SingleThreadSaver;
import com.nssc.exam.common.Tools;
import com.nssc.exam.self.model.TStudentPhoto;
public class SelfStudentPhotoSaver extends SingleThreadSaver {
private IStudentService studentService = null;
private File folder = null;
private Date optTime = null;
private long userId = -1L;
@Override
public void save() {
importPhotosUnderThisFolder(folder, optTime, userId);
}
private void importPhotosUnderThisFolder(File pFolder, Date optTime, long userId) {
if(pFolder == null || !pFolder.canRead()) {
return;
}
if(pFolder.isFile()) {
try {
if(!pFolder.getName().toUpperCase().endsWith(".JPG")) {
return;
}
String fileName = pFolder.getName().toUpperCase().trim();
String zkz = fileName.substring(0, fileName.indexOf(".JPG"));
if(zkz.length() > 12) {
addErrorMsg("准考证不合法:" + zkz + "(" + pFolder.getAbsolutePath() + ")");
increaseErrorCount();
return;
}
TStudentPhoto sp = new TStudentPhoto();
sp.setZkz(zkz);
sp.setPhotoContent(Tools.getBytesFromFile(pFolder));
sp.setOperateTime(optTime);
sp.setOperateUserId(userId);
if(studentService.uploadStudentPhoto(sp)) {
increaseSuccessCount();
} else {
increaseErrorCount();
}
return;
} catch(Exception e) {
e.printStackTrace();
addErrorMsg(e.getMessage());
increaseErrorCount();
return;
}
}
if(pFolder.listFiles() == null) {
return;
}
for(File subFolder : pFolder.listFiles()) {
importPhotosUnderThisFolder(subFolder, optTime, userId);
}
}
public static void main(String[] args)
throws Exception{
SelfStudentPhotoSaver saver = SelfStudentPhotoSaver.class.newInstance();
System.out.println(saver);
}
public IStudentService getStudentService() {
return studentService;
}
public void setStudentService(IStudentService studentService) {
this.studentService = studentService;
}
public File getFolder() {
return folder;
}
public void setFolder(File folder) {
this.folder = folder;
}
public Date getOptTime() {
return optTime;
}
public void setOptTime(Date optTime) {
this.optTime = optTime;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
}
分享到:
相关推荐
在C++/CLI中声明泛型类或方法时,使用`generic <typename T>`关键字,其中`T`是类型参数。例如,可以创建一个泛型栈`Stack`,如下所示: ```cpp generic ref class Stack { public: void Push(ItemType item) {…}...
C++设计新思维:泛型编程与设计模式之应用.pdf 带目录书签
7. 高级泛型:课程还将涉及一些高级泛型主题,如协变和逆变、泛型接口的继承以及泛型的嵌套。这些特性使得泛型能适应更复杂的编程场景。 8. 示例与实践:为了帮助学员更好地掌握泛型,课程会结合大量实例进行教学,...
2. 线程同步:掌握互斥量(mutexes)、条件变量(condition variables)、信号量(semaphores)等同步机制,防止数据竞争和死锁。 3. 并发容器与算法:了解并发安全的容器(如std::vector, std::queue)和并发安全的...
泛型方法允许我们在单个方法中处理多种数据类型。方法内的类型参数与类的类型参数类似,只是它们仅限于该方法的范围。下面的例子展示了一个返回两个参数最大值的泛型方法: ```csharp public static T MaxValue(T a...
6. 级联泛型:如`List<List<String>>`表示列表的元素是字符串列表。 7. 类型推断:Java编译器可以根据上下文自动推断类型参数,例如在lambda表达式和方法引用中。 8. 对于数组,由于历史原因,Java的泛型不支持...
泛型编程是C++设计哲学的一个重要组成部分,它通过模板机制允许程序员编写与数据类型无关的代码,这种设计使得编写的代码不仅可以复用,而且在面对不同类型的数据时也具有更好的灵活性。在《C++设计新思维》中,作者...
"泛型、泛型擦除、桥接方法" 泛型是一种类型参数化技术,允许开发者在编写代码时指定类型,提高代码的灵活性和可重用性。泛型可以应用于接口、类和方法中,称之为泛型接口、泛型类和泛型方法。 泛型接口是指在接口...
泛型主要分为四个关键部分:泛型类、泛型方法、泛型接口和泛型委托。下面将详细介绍这四个方面。 1. 泛型类: 泛型类是具有一个或多个类型参数的类。这些类型参数是占位符,代表一种未知的数据类型,直到在创建类...
在C#编程中,方法异常和泛型是两个至关重要的概念。它们构成了C#语言功能的核心部分,并在软件开发中发挥着关键作用。理解和熟练掌握这两个主题,将有助于提升你的编程技能,无论你是初学者还是有经验的开发者。 ...
编程选择题40道:泛型:类型安全与泛型编程.Tex.docx
- 方法级别的泛型:如`public <E> void printList(E[] elements)`,方法内的E仅在此方法内有效。 - 泛型通配符:例如`?`,表示任意类型。`List<?>`表示可以容纳任何类型的列表。 - 上界通配符:`<? extends T>`...
C++ 设计新思维:泛型编程与设计模式之应用C++ 设计新思维:泛型编程与设计模式之应用C++ 设计新思维:泛型编程与设计模式之应用C++ 设计新思维:泛型编程与设计模式之应用C++ 设计新思维:泛型编程与设计模式之应用
首先,泛型的基本概念是允许在定义类、接口和方法时使用类型参数,这样就可以在编译时检查类型安全,并且可以重用相同的代码处理不同的数据类型。例如,ArrayList是一个典型的泛型类,它可以被声明为ArrayList或...
泛型+反射:泛型 笔记 ,课后作业
泛型是Java编程语言中用于减少类型转换错误和增强代码安全性的机制,它允许在定义类、接口和方法时使用类型参数。通过这种方式,可以在编译时期捕获那些只有在运行时期才会暴露的类型错误,提高了代码的健壮性。 ...
【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 ) https://hanshuliang.blog.csdn.net/article/details/114059611 博客源码快照
泛型允许开发者定义通用的数据结构和方法,而不必为每种特定的数据类型创建单独的类或接口。这使得代码更加简洁、高效,同时也避免了类型转换带来的潜在错误和性能损失。 在C#中,泛型类定义时,使用尖括号`<T>`来...