技术总结(2021/08/16)

 目录

一、Java钩子方法addShutdownHook

 二、终止线程池对应某个线程

三、通过ExecutorCompletionService实现任务结果的获取

四、group by遇到null值

五、sql语句中条件语句where后的多个and/or的优先级

六、JAVA Set 交集,差集,并集

七、java判断时间格式

八、Stream流使用汇总


一、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);
		}
	}
});

 二、终止线程池对应某个线程

 思路:

  1. 创建一个hashMap,将所创建的线程以及对应每个线程唯一标识放进去:consoleThreadMap.put(serial, Thread.currentThread());
  2. 在线程正常执行结束后从hashMap中移除:consoleThreadMap.remove(serial);
  3. 如果需要移除的线程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;
	}
}

八、Stream流使用汇总

java8 Stream多字段排序

java8 Lambda Stream collect Collectors 常用实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值