一些方法
自定义类加载器
import javassist.ClassPool;
/**
* @author 99013
* @ClassName MyClassLoader
* @Description 自定义类加载器
* 作者:99013
* 创建时间:2022年02月17日 15:36:54
* @Version 1.0
**/
public class MyClassLoader extends ClassLoader {
// 类池
private static ClassPool pool;
/**
* 利用子类池覆盖默认类池,从而防止ClassPool中类越来越多的情况
* @return javassist.ClassPool
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2022年05月24日 14:33:11
*/
public static ClassPool getClassPool() {
return new ClassPool(getPool());
}
/**
* 初始默认类池
* @return javassist.ClassPool
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2022年05月24日 14:35:01
*/
private static ClassPool getPool() {
if (pool == null) {
pool = ClassPool.getDefault();
}
return pool;
}
public Class<?> defineClass(String name, byte[] b) {
// ClassLoader是个抽象类,而ClassLoader.defineClass 方法是protected的
// 所以我们需要定义一个子类将这个方法暴露出来
return super.defineClass(name, b, 0, b.length);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// 根据类的全类名进行加锁操作,也就是保证了线程安全
synchronized (getClassLoadingLock(name)) {
Class<?> klass = findLoadedClass(name);
// 到已经加载的缓存中查看是否已经被加载了如果是则直接返回,如果没有就需要进行加载
if (klass == null) {
// 如果缓存中没有,则表示这个类是第一次被加载,对于类进行判断操作
if (name.startsWith("java.") || name.startsWith("javax.")) {
try {
klass = getSystemClassLoader().loadClass(name);
} catch (Exception e) {
throw e;
}
// 如果不满足要求则表示使用自定义的类加载器进行加载操作。
} else {
try {
klass = this.findClass(name);
} catch (Exception ignored) {
}
// 如果自定义加载器没有完成则需要交给父类加载器去进行加载操作
if (klass == null) {
if (getParent() != null) {
klass = getParent().loadClass(name);
} else {
klass = getSystemClassLoader().loadClass(name);
}
}
}
}
// 如果加载不成功的话就抛出异常。
if (null == klass) {
throw new ClassNotFoundException("The class " + name + " not found.");
}
if (resolve) {
resolveClass(klass);
}
return klass;
}
}
}
自定义线程池
import java.util.concurrent.*;
/**
* 自定义线程池
* 描述:TODO
* @作者 <b><a class=b href="https://blog.csdn.net/lingdu_dou" color="red">⭕°</a></b>
* @创建时间 2022-08-26 11:01
*/
public class MyThreadPool {
public static ExecutorService threadPool;
static {
newThreadPool();
}
/**
* 1⚫corePoolSize线程池的核心线程数
* 线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,
* 除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。
* 2⚫maximumPoolSize能容纳的最大线程数
* 一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,
* 如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,
* 然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。
* 线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。
* 3⚫keepAliveTime空闲线程存活时间
* 一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,
* 这里的指定时间由keepAliveTime来设定
* 4⚫unit 空闲线程存活时间单位
* 5⚫workQueue 存放提交但未执行任务的队列
* 新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:
* ArrayBlockingQueue
* 基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。
* 当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。
* 如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
* LinkedBlockingQuene
* 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,
* 当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,
* 因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
* SynchronousQuene
* 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,
* 而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
* PriorityBlockingQueue
* 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
* 6⚫threadFactory 创建线程的工厂类
* 创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等
* 7⚫handler 等待队列满后的拒绝策略
* 当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,
* 该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:
* CallerRunsPolicy
* 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务
* AbortPolicy
* 该策略下,直接丢弃任务,并抛出RejectedExecutionException异常
* DiscardPolicy
* 该策略下,直接丢弃任务,什么都不做
* DiscardOldestPolicy
* 该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
*/
private static void newThreadPool() {
threadPool = new ThreadPoolExecutor(10, 50,
1L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(50),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
}
}
调用
class A {
public void start() {
MyThreadPool.threadPool.execute(this::init);
}
public void init() {
// 业务逻辑
}
}
class B {
private void addDataSource(SysDatabase d) {
MyThreadPool.threadPool.execute(() -> addDataSource(d, false));
}
public boolean addDataSource(SysDatabase d, boolean test) {
// 业务逻辑
}
}
class C {
private void c(int a, int b) {
if(a>b){
MyThreadPool.threadPool.execute(() -> {
// 存量推送处理
stockPush(kds);
// 更新启动线程列表和版本号
updateDataVersion(RedisDataVersion.KAFKA_CONSUMER_THREAD_NAMES, keySet);
});
return;
}
if(a<b){
// ............
}
}
}
Java代码中验证IP地址是否可访问【Linux和windows环境下】
说明
我的需求场景是尝试连接数据源,数据库地址有不同网络环境下的地址{生产、内网、局域网等},所以在连接数据源之前判断一下url中的ip是否可访问,然后决定是否执行下一步操作。
提取字符串中的IP
class A {
/**
* 提取字符串中的IP集合
* @param line 目标字符
* @return 返回所有发现的IP
* @作者 <b><a class=b href="https://blog.csdn.net/lingdu_dou" color="red">⭕°</a></b>
* @创建时间 2022-08-30 11:20 */
public static List<String> extractIp(String line) {
List<String> ips = new ArrayList<>();
if (line != null) {
String regex = "(^|[^\\d])(((2[0-4]\\d|25[0-5]|1\\d\\d|\\d\\d?)\\.){3}(2[0-4]\\d|25\\d|1\\d\\d|\\d\\d?))";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(line);
while (m.find()) {
ips.add(m.group(2));
}
}
return ips;
}
}
检查是否可访问
class A {
/**
* 测试网址是否可访问
* @param ip ip地址
* @return 返回true可访问 返回false不可访问
* @作者 <b><a class=b href="https://blog.csdn.net/lingdu_dou" color="red">⭕°</a></b>
* @创建时间 2022-08-31 9:05 */
public static boolean ping(String ip) {
//获取操作系统类型
String osName = System.getProperty("os.name");
log.info("操作系统:" + osName);
String command = "";
if (osName.contains("Linux")) {
command = "ping -c 1 -w 1 " + ip;
} else if (osName.contains("Windows")) {
command = "ping -n 1 -w 1000 " + ip;
} else {
log.error("未知系统 执行ping命令失败");
return false;
}
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream(), "GBK"));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if (line.contains("来自") || line.contains("1 received")) {
log.info(ip + " 连接成功");
return true;
}
if (line.contains("请求超时") || line.contains("0 received")) {
log.info(ip + " 连接失败");
return false;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
java模拟HTTP请求工具
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
/**
* java模拟HTTP请求工具
*
* @author 99013
* @ClassName HttpRequestUtil
* @Description TODO
* 作者:99013
* 创建时间:2020年12月03日 14:07:35
* @Version 2.0
**/
public class HttpRequestUtil {
private static final Logger log = LoggerFactory.getLogger(HttpRequestUtil.class);
/**
* POST请求
*/
public static final String POST = "POST";
/**
* PUT请求
*/
public static final String PUT = "PUT";
/**
* GET请求
*/
public static final String GET = "GET";
/**
* DELETE请求
*/
public static final String DELETE = "DELETE";
/**
* utf-8
*/
public static final String CHARSET_UTF8 = "UTF-8";
/**
* 请求内容类型
*/
public static final String CONTENT_TYPE = "Content-type";
/**
* 请求通用格式
*/
public static final String CONTENT_TYPE_JSON = "application/json";
/**
* multipart/form-data类型
*/
public static final String CONTENT_TYPE_FORMDATA = "multipart/form-data";
public static String CONTENT_TYPE_WAY;
/**
* text/plain类型
*/
public static final String CONTENT_TYPE_TEXT_PLAIN = "text/plain";
/**
* image/jpeg类型
*/
public static final String MIME_TYPE_IMAGE_JPEG = "image/jpeg";
/**
* 边界
*/
private static final String BOUNDARY = "----WebKitFormBoundary07I8UIuBx6LN2KyY";
/**
* Get请求
*
* @param url 请求路径
* @param params 请求参数
* @param cookie Cookie
* @param headerMap 请求头补充参数
* @return java.lang.String
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2021年08月26日 18:46:43
*/
public static String sendGet(String url, Map<String, Object> params, String cookie, Map<String, Object> headerMap) {
return send(GET, url, params, null, cookie, headerMap, null, null);
}
/**
* Delete请求
*
* @param url 请求路径
* @param params 请求参数
* @param cookie cookie
* @param headerMap 请求头补充参数
* @return java.lang.String
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2021年08月26日 18:48:02
*/
public static String sendDelete(String url, Map<String, Object> params, String cookie, Map<String, Object> headerMap) {
return send(DELETE, url, params, null, cookie, headerMap, null, null);
}
/**
* Post请求
*
* @param url 第三方接口地址
* @param params 请求参数
* @param pjson json方式传参
* @param cookie cookie
* @param headerMap 请求头补充参数
* @return java.lang.String 返回信息
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2020年12月03日 17:45:21
*/
public static String sendPost(String url, Map<String, Object> params, String pjson, String cookie, Map<String, Object> headerMap) {
return sendPostUplodFile(url, params, pjson, cookie, headerMap, null, null);
}
/**
* 模拟http请求上传文件及相关参数
*
* @param url 第三方上传文件地址
* @param fileName 文件名
* @param params 请求参数
* @param bytes 文件字节码
* @param cookie Cookie
* @return java.lang.String
*/
public static String sendPostUplodFile(String url, Map<String, Object> params, String pjson, String cookie, Map<String, Object> headerMap, String fileName, byte[] bytes) {
return send(POST, url, params, pjson, cookie, headerMap, fileName, bytes);
}
/**
* put请求方式
*
* @param url 请求路径
* @param params 请求参数
* @param cookie cookie
* @return java.lang.String
* 创建时间: 2021年03月07日 09:16:34
*/
public static String sendPut(String url, Map<String, Object> params, String pjson, String cookie, Map<String, Object> headerMap) {
return send(PUT, url, params, pjson, cookie, headerMap, null, null);
}
/**
* put请求方式 上传文件
*
* @param url 请求路径
* @param fileName 文件名
* @param params 请求参数
* @param pjson json传参数
* @param bytes 文件字节码
* @param cookie cookie
* @return java.lang.String
* 创建时间: 2021年03月07日 09:16:34
*/
public static String sendPutUplodFile(String url, Map<String, Object> params, String pjson, String cookie, Map<String, Object> headerMap, String fileName, byte[] bytes) {
return send(PUT, url, params, pjson, cookie, headerMap, fileName, bytes);
}
/**
* 执行请求
*
* @param type 请求类型
* @param url 第三方请求地址
* @param params 请求参数
* @param pjson json参数
* @param cookie Cookie
* @param headerMap 补充请求头参数
* @param fileName 文件名
* @param bytes 文件字节码
* @return java.lang.String
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2021年08月26日 18:21:34
*/
public static String send(String type, String url, Map<String, Object> params, String pjson, String cookie, Map<String, Object> headerMap, String fileName, byte[] bytes) {
DataOutputStream out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
// GET 和 DELETE 请求
if (type.equals(GET) || type.equals(DELETE)) {
if (params != null) {
StringBuilder urlBuilder = new StringBuilder(url + "?");
for (String s : params.keySet()) {
// 防 止 中 文 乱 码 ↓
urlBuilder.append(s).append("=").append(URLEncoder.encode(params.get(s).toString(), CHARSET_UTF8)).append("&");
}
url = urlBuilder.toString();
}
}
// 默认表单提交
CONTENT_TYPE_WAY = CONTENT_TYPE_FORMDATA;
// 如果pjson不为空则使用json方式提交
if (pjson != null) {
CONTENT_TYPE_WAY = CONTENT_TYPE_JSON;
}
//打开和URL之间的连接
HttpURLConnection conn = getHttpUrlConnection(url, type, cookie, headerMap);
// POST 和 PUT 请求
if (type.equals(POST) || type.equals(PUT)) {
out = new DataOutputStream(conn.getOutputStream());
//添加参数
if (params != null) {
for (String key : params.keySet()) {
String sb = "--" +
BOUNDARY +
"\r\n" +
"Content-Disposition: form-data;name=\"" + key + "\"" +
"\r\n" +
"\r\n" +
params.get(key) +
// URLEncoder.encode(params.get(key).toString(), "utf-8")+
"\r\n";
out.write(sb.getBytes());
}
}
// 传文件
if (null != fileName && null != bytes) {
//添加参数file
String sb = "--" +
BOUNDARY +
"\r\n" +
"Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"" +
"\r\n" +
"Content-Type: " + MIME_TYPE_IMAGE_JPEG +
"\r\n" +
"\r\n";
out.write(sb.getBytes());
// TODO 写文件
out.write(bytes);
out.write("\r\n".getBytes());
}
if (pjson != null) {
out.writeBytes(pjson);
} else {
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
}
//flush输出流的缓冲
out.flush();
}
//定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
log.error("发送请求出现异常:", e);
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return result.toString();
}
/**
* 和URL之间建立连接
*
* @param url 请求路径
* @param type 请求类型
* @param cookie cookie
* @param headerMap 请求头补充参数
* @return java.net.HttpURLConnection 返回连接信息
* <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
* 创建时间: 2021年09月02日 15:51:28
*/
private static HttpURLConnection getHttpUrlConnection(String url, String type, String cookie, Map<String, Object> headerMap) throws IOException {
URL realUrl = new URL(url);
//打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
if (POST.equals(type) || PUT.equals(type)) {
//发送POST请求必须设置如下两行
// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
conn.setDoOutput(true);
// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
conn.setDoInput(true);
}
conn.setUseCaches(false);
conn.setRequestMethod(type);
// 设置连接主机服务器超时时间:15000毫秒
conn.setConnectTimeout(15000);
// 设置读取主机服务器返回数据超时时间:60000毫秒
conn.setReadTimeout(60000);
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36");
conn.setRequestProperty("Charsert", CHARSET_UTF8);
if (cookie != null) {
conn.setRequestProperty("Cookie", cookie);
}
conn.setRequestProperty(CONTENT_TYPE, CONTENT_TYPE_WAY + "; boundary=" + BOUNDARY);
//填充请求头
if (headerMap != null && headerMap.keySet().size() != 0) {
for (String s : headerMap.keySet()) {
conn.setRequestProperty(s, headerMap.get(s).toString());
}
}
conn.connect();
return conn;
}
}