目录
三、通过ExecutorCompletionService实现任务结果的获取
五、sql语句中条件语句where后的多个and/or的优先级
一、Java钩子方法addShutdownHook
使用 java.lang.Runtime.addShutdownHook() 钩子程序,可以在JVM正常退出时做一些事情,JVM关闭方式有一下三种:
- 正常关闭:当最后一个非守护线程结束或者调用了System.exit或者通过其他特定平台的方法关闭(发送SIGINT(2),SIGTERM(15)信号等)
- 强制关闭:通过调用Runtime.halt方法或者是在操作系统中直接kill(发送SIGKILL(9)信号)掉JVM进程
- 异常关闭:运行中遇到RuntimeException异常等。
// 当用kill -15结束进程时钩子程序运行,kill -9强杀不运行。
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
if (warningTaskContainer!=null && warningTaskContainer.size()>0) {
Collection<WarningTask> warningTasks = warningTaskContainer.values();
stopTask(warningTasks);
}
}
});
二、终止线程池对应某个线程
思路:
- 创建一个hashMap,将所创建的线程以及对应每个线程唯一标识放进去:consoleThreadMap.put(serial, Thread.currentThread());
- 在线程正常执行结束后从hashMap中移除:consoleThreadMap.remove(serial);
- 如果需要移除的线程m在正常运行中需要移除,则执行consoleThreadMap.get(serial).interrupt();
public static ConcurrentHashMap<String, Thread> warningTaskThreadMap = new ConcurrentHashMap<String, Thread>();
private ExecutorService executorService = Executors.newFixedThreadPool(5);
class WarningTaskProcess implements Runnable {
private String taskId;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
@Override
public void run() {
try {
warningTaskThreadMap.put(taskId, Thread.currentThread());
executeTask(taskId);
} finally {
warningTaskThreadMap.remove(taskId);
}
}
}
三、通过ExecutorCompletionService实现任务结果的获取
通过ExecutorCompletionService实现任务结果的获取,可以实现将完成的任务先获取。按照这些任务的完成的时间顺序来处理他们的结果。
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExecutorCallableTest {
public static void main(String[] args) {
//创建一个线程池
ExecutorService pools = Executors.newFixedThreadPool(5);
CompletionService<Integer> s = new ExecutorCompletionService<Integer>(pools);
//创建多个有返回值的任务
for(int i = 0 ; i <= 10 ; i++){
s.submit(new Task(i));
}
for(int i = 0 ; i <= 10 ; i++){
try {
Future<Integer> f = s.take();
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
pools.shutdown();
}
}
class Task implements Callable<Integer>{
private Integer taskID;
public Task(Integer taskID) {
this.taskID = taskID;
}
public Integer call() throws Exception {
if(taskID.equals(3))
Thread.sleep(10000);
System.out.println("任务["+taskID+"]开始执行");
return taskID;
}
}
任务[1]开始执行
任务[4]开始执行
任务[5]开始执行
任务[6]开始执行
任务[0]开始执行
任务[2]开始执行
任务[9]开始执行
任务[8]开始执行
任务[7]开始执行
4
1
任务[10]开始执行
5
6
0
2
9
8
7
10
任务[3]开始执行
3
四、group by遇到null值
当group by这列有null值时,group会把他们当成是同一个直接聚合。
但我现在需要把b.name=NULL的情况都查询出来,而不是聚合,那么怎么办?
#--增加一个UUID(),把b.name的NULL的值都转化为具有专一性的uuid,这样每个b.name都会不同,GROUP就不会对他们进行分组
SELECT a.id ,a.name ,b.name FROM A a
LEFT JOIN B b
ON(a.id = b.aid)
GROUP BY IFNULL(b.name,UUID());
五、sql语句中条件语句where后的多个and/or的优先级
SQL解析器在处理操作时会优先处理and操作:
select * from product where product_id = 100 or product_id = 101 and product_price > 200
上述代码中,SQL解析器首先进行and 的操作,最后就成了这个意思:查找产品号为101且价格大于200或产品号为100 的商品。
添加圆括号即可:select * from product where (product_id = 100 or product_id = 101) and product_price > 200
六、JAVA Set 交集,差集,并集
import java.util.HashSet;
import java.util.Set;
public class TestSet {
public static void main(String[] args) {
Set<String> result = new HashSet<String>();
Set<String> set1 = new HashSet<String>() {
{
add("王者荣耀");
add("英雄联盟");
add("穿越火线");
add("地下城与勇士");
}
};
Set<String> set2 = new HashSet<String>() {
{
add("王者荣耀");
add("地下城与勇士");
add("魔兽世界");
}
};
result.clear();
result.addAll(set1);
result.retainAll(set2);
System.out.println("交集:" + result);
result.clear();
result.addAll(set1);
result.removeAll(set2);
System.out.println("差集:" + result);
result.clear();
result.addAll(set1);
result.addAll(set2);
System.out.println("并集:" + result);
}
}
七、java判断时间格式
public static final String PATTERN_DEFAULT = "yyyy-MM-dd HH:mm:ss";
private Boolean isDateVail(String date) {
//用于指定 日期/时间 模式
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DateTimeUtil.PATTERN_DEFAULT);
boolean flag = true;
try {
//Java 8 新添API 用于解析日期和时间
LocalDateTime.parse(date, dtf);
} catch (Exception e) {
flag = false;
}
return flag;
}
/**
* 判断时间格式 格式必须为“YYYY-MM-dd”
* @param sDate
* @return
*/
public boolean isValidDate(String str) {
//String str = "2007-01-02";
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
try{
Date date = (Date)formatter.parse(str);
DebugPrintf.Printf(str);
DebugPrintf.Printf(formatter.format(date));
return str.equals(formatter.format(date));
}catch(Exception e){
return false;
}
}