如果面对一大块代码不知如何下手,那么就从小处着手,先动起来。 对于如下代码,了解 Java8 Stream api 的同学肯定知道怎么做了:
public List getData(List keys) {
// maybe xxxService.getData(keys);
List result = new ArrayList();
for (String key: keys) {
result.add(Integer.valueOf(key) % 1000000000);
}
return result;
}
for (String part: parts) {
int start = Integer.parseInt(part.split(":")[0]);
int end = Integer.parseInt(part.split(":")[1]);
if (end > allKeys.size()) {
end = allKeys.size();
}
final List tmpRowkeyList = allKeys.subList(start, end);
// submit tasks
}
package zzz.study.function.refactor.result;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import zzz.study.function.refactor.CatchUtil;
import zzz.study.function.refactor.ExecutorUtil;
import zzz.study.function.refactor.ForeachUtil;
import zzz.study.function.refactor.StreamUtil;
/**
* Created by shuqin on 17/6/23.
*/
public class ConcurrentDataHandlerFrameRefactored {
public static void main(String[] args) {
List allData = getAllData(DataSupplier::getKeys, GetTradeData::getData);
consumer(allData, System.out::println);
List handledData = handleAllData(allData,
(numbers) -> StreamUtil.map(numbers, (num) -> Math.sqrt(num)) );
consumer(handledData, System.out::println);
List objs = StreamUtil.map(DataSupplier.getKeys(), s->Double.valueOf(s));
List handledData2 =
handleAllData((numbers) -> StreamUtil.map(numbers, (num) -> Math.pow((double)num,2))).apply(objs);
consumer(handledData2, System.out::println);
Function, List> func = (numbers) -> StreamUtil.map(numbers, (num) -> Integer.parseInt(num)*2);
List handledData3 =
handleAllData(DataSupplier::getKeys).apply(func);
consumer(handledData3, System.out::println);
}
/**
* 获取所有业务数据
*
* 回调的替换
*/
public static List getAllData(Supplier> getAllKeysFunc, Function, List> iGetBizDataFunc) {
return getAllData(getAllKeysFunc.get(), iGetBizDataFunc);
}
public static List getAllData(List allKeys, Function, List> iGetBizDataFunc) {
return handleAllData(allKeys, iGetBizDataFunc);
}
public static List handleAllData(Supplier> getAllKeysFunc, Function, List> handleBizDataFunc) {
return handleAllData(getAllKeysFunc.get(), handleBizDataFunc);
}
/**
* 传入一个数据处理函数,返回一个可以并发处理数据集的函数, 该函数接受一个指定数据集
* Java 模拟柯里化: 函数工厂
*/
public static Function, List> handleAllData(Function, List> handleBizDataFunc) {
return ts -> handleAllData(ts, handleBizDataFunc);
}
/**
* 传入一个数据提供函数,返回一个可以并发处理获取的数据集的函数, 该函数接受一个数据处理函数
* Java 模拟柯里化: 函数工厂
*/
public static Function, List>, List> handleAllData(Supplier> getAllKeysFunc) {
return handleBizDataFunc -> handleAllData(getAllKeysFunc.get(), handleBizDataFunc);
}
public static List handleAllData(List allKeys, Function, List> handleBizDataFunc) {
return ExecutorUtil.exec(allKeys, handleBizDataFunc);
}
public static void consumer(List data, Consumer consumer) {
data.forEach( (t) -> CatchUtil.tryDo(t, consumer) );
}
public static class DataSupplier {
public static List getKeys() {
// foreach code refining
return ForeachUtil.foreachAddWithReturn(2000, (ind -> Arrays.asList(String.valueOf(ind))));
}
}
/** 获取业务数据具体实现 */
public static class GetTradeData {
public static List getData(List keys) {
// maybe xxxService.getData(keys);
return StreamUtil.map(keys, key -> Integer.valueOf(key) % 1000000000); // stream replace foreach
}
}
}
ExecutorUtil
package zzz.study.function.refactor;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Created by shuqin on 17/6/25.
*/
public class ExecutorUtil {
private ExecutorUtil() {}
private static final int CORE_CPUS = Runtime.getRuntime().availableProcessors();
private static final int TASK_SIZE = 1000;
// a throol pool may be managed by spring
private static ExecutorService executor = new ThreadPoolExecutor(
CORE_CPUS, 10, 60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(60));
/**
* 根据指定的列表关键数据及列表数据处理器,并发地处理并返回处理后的列表数据集合
* @param allKeys 列表关键数据
* @param handleBizDataFunc 列表数据处理器
* @param 待处理的数据参数类型
* @param 待返回的数据结果类型
* @return 处理后的列表数据集合
*
* NOTE: 类似实现了 stream.par.map 的功能,不带延迟计算
*/
public static List exec(List allKeys, Function, List> handleBizDataFunc) {
List parts = TaskUtil.divide(allKeys.size(), TASK_SIZE);
//System.out.println(parts);
CompletionService>
completionService = new ExecutorCompletionService<>(executor);
ForeachUtil.foreachDone(parts, (part) -> {
final List tmpRowkeyList = TaskUtil.getSubList(allKeys, part);
completionService.submit(
() -> handleBizDataFunc.apply(tmpRowkeyList)); // lambda replace inner class
});
// foreach code refining
List result = ForeachUtil.foreachAddWithReturn(parts.size(), (ind) -> get(ind, completionService));
return result;
}
/**
* 根据指定的列表关键数据及列表数据处理器,并发地处理
* @param allKeys 列表关键数据
* @param handleBizDataFunc 列表数据处理器
* @param 待处理的数据参数类型
*
* NOTE: foreachDone 的并发版
*/
public static void exec(List allKeys, Consumer> handleBizDataFunc) {
List parts = TaskUtil.divide(allKeys.size(), TASK_SIZE);
//System.out.println(parts);
ForeachUtil.foreachDone(parts, (part) -> {
final List tmpRowkeyList = TaskUtil.getSubList(allKeys, part);
executor.execute(
() -> handleBizDataFunc.accept(tmpRowkeyList)); // lambda replace inner class
});
}
public static List get(int ind, CompletionService> completionService) {
// lambda cannot handler checked exception
try {
return completionService.take().get();
} catch (Exception e) {
e.printStackTrace(); // for log
throw new RuntimeException(e.getCause());
}
}
}
TaskUtil
package zzz.study.function.refactor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by shuqin on 17/1/5.
*/
public class TaskUtil {
private TaskUtil() {}
public static List divide(int totalSize, int persize) {
List parts = new ArrayList();
if (totalSize <= 0 || persize <= 0) {
return parts;
}
if (persize >= totalSize) {
parts.add("0:" + totalSize);
return parts;
}
int num = totalSize / persize + (totalSize % persize == 0 ? 0 : 1);
for (int i=0; i totalSize) {
end = totalSize;
}
parts.add(start + ":" + end);
}
return parts;
}
public static List getSubList(List allKeys, String part) {
int start = Integer.parseInt(part.split(":")[0]);
int end = Integer.parseInt(part.split(":")[1]);
if (end > allKeys.size()) {
end = allKeys.size();
}
return allKeys.subList(start, end);
}
}
package zzz.study.function.refactor;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Created by shuqin on 17/6/24.
*
* foreach 代码通用模板
*/
public class ForeachUtil {
public static List foreachAddWithReturn(int num, Function> getFunc) {
List result = new ArrayList();
for (int i=0; i< num; i++) {
result.addAll(CatchUtil.tryDo(i, getFunc));
}
return result;
}
public static void foreachDone(List data, Consumer doFunc) {
for (T part: data) {
CatchUtil.tryDo(part, doFunc);
}
}
}
CatchUtil
package zzz.study.function.refactor;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Created by shuqin on 17/6/24.
*/
public class CatchUtil {
public static R tryDo(T t, Function func) {
try {
return func.apply(t);
} catch (Exception e) {
e.printStackTrace(); // for log
throw new RuntimeException(e.getCause());
}
}
public static void tryDo(T t, Consumer func) {
try {
func.accept(t);
} catch (Exception e) {
e.printStackTrace(); // for log
throw new RuntimeException(e.getCause());
}
}
}
StreamUtil
package zzz.study.function.refactor;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Created by shuqin on 17/6/24.
*/
public class StreamUtil {
public static List map(List data, Function mapFunc) {
return data.stream().map(mapFunc).collect(Collectors.toList()); // stream replace foreach
}
}
本文首先介绍下MongoDB的基本的增删改查操作,然后,详细介绍MongoDB提供的修改器,以完成各种各样的文档更新操作 MongoDB的主要操作
show dbs 显示当前用户能看到哪些数据库
use foobar 将数据库切换到foobar
show collections 显示当前数据库有哪些集合
db.people.update,update不带参数,可
The alert log is a chronological log of messages and errors, and includes the following items:
All internal errors (ORA-00600), block corruption errors (ORA-01578), and deadlock errors (ORA-00060)
由于几年前写了几篇 CAS 系列的文章,之后陆续有人参照文章去实现,可都遇到了各种问题,同时经常或多或少的收到不少人的求助。现在这时特此说明几点:
1. 那些文章发表于好几年前了,CAS 已经更新几个很多版本了,由于近年已经没有做该领域方面的事情,所有文章也没有持续更新。
2. 文章只是提供思路,尽管 CAS 版本已经发生变化,但原理和流程仍然一致。最重要的是明白原理,然后
lesson 课
traffic 交通
matter 要紧;事物
happy 快乐的,幸福的
second 第二的
idea 主意;想法;意见
mean 意味着
important 重要的,重大的
never 从来,决不
afraid 害怕 的
fifth 第五的
hometown 故乡,家乡
discuss 讨论;议论
east 东方的
agree 同意;赞成
bo
这次看下spring中少见的注解@primary注解,例子
@Component
public class MetalSinger implements Singer{
@Override
public String sing(String lyrics) {
return "I am singing with DIO voice