ThreadHelper.java 6.61 KB
package com.yanzuoguang.util.thread;

import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.exception.ExceptionHelper;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程帮助类
 * @author 颜佐光
 */
public class ThreadHelper {
    private static Object threadLock = new Object();
    private static boolean threadIsRun = false;
    private static Date threadDate = null;
    private static RunPlan timeout;
    private static RunPlan interval;
    private static final long SECOND_UNIT = 1000;
    private static final long NEXT_SECOND = 5;
    /**
     * 线程对象
     */
    private static ExecutorService executeService = Executors.newCachedThreadPool();

    /**
     * 初始化线程对象,需要调用该函数之后才能使用
     */
    public static void init() {
        if (timeout != null || interval != null) {
            return;
        }
        threadDate = DateHelper.getDateTime("1987-11-04");
        timeout = new RunPlan();
        interval = new RunPlan();
        Runnable addExecute = new Runnable() {
            @Override
            public void run() {
                onExecuteAdd();
            }
        };
        Runnable itemExecuted = new Runnable() {
            @Override
            public void run() {
                onItemExecuted();
            }
        };
        timeout.getOnAdd().add(addExecute);
        timeout.getOnItemExecuted().add(itemExecuted);
        interval.getOnAdd().add(addExecute);
        interval.getOnItemExecuted().add(itemExecuted);
        startMonitor();
    }

    private static void onItemExecuted() {
        threadDate = new Date();
    }

    private static void onExecuteAdd() {
        startThread();
    }

    private static void startThread() {
        synchronized (threadLock) {
            if (threadIsRun) {
                return;
            }
            runThread(new Runnable() {
                @Override
                public void run() {
                    threadIsRun = true;
                    while (threadIsRun) {
                        try {
                            timeout.run(true, -1);
                        } catch (Exception ex) {
                            ExceptionHelper.handleException(ThreadHelper.class, ex);
                        }
                        try {
                            interval.run(false, -1);
                        } catch (Exception ex) {
                            ExceptionHelper.handleException(ThreadHelper.class, ex);
                        }
                        if (timeout.getCount() == 0 && interval.getCount() == 0) {
                            break;
                        }
                        sleep(10);
                    }
                    threadIsRun = false;
                }
            });
        }
    }

    /**
     * 监控线程的方法,防止线程执行死机
     */
    private static void startMonitor() {
        runThread(new Runnable() {

            @Override
            public void run() {
                do {
                    if (threadIsRun && ((System.currentTimeMillis() - threadDate.getTime()) / SECOND_UNIT) > NEXT_SECOND) {
                        try {
                            if (threadIsRun) {
                                threadIsRun = false;
                            }
                        } catch (Exception ex) {
                            ExceptionHelper.handleException(ThreadHelper.class, ex);
                        }
                        threadIsRun = false;
                        startThread();
                    }
                    sleep(1000 * 60);
                } while (true);
            }
        });
    }

    /**
     * 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
     *
     * @param run   需要执行的程序
     * @param vTime 间隔时间
     * @return 执行标志
     */
    public static String setTimeout(Runnable run, int vTime) {
        return timeout.set(run, vTime);
    }

    /**
     * 清除需要执行的任务
     *
     * @param flag 执行标志
     */
    public static void clearTimeout(String flag) {
        timeout.remove(flag);
    }

    /**
     * 清除需要执行的任务
     *
     * @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
     */
    public static void clearTimeout(Runnable run) {
        timeout.remove(run);
    }

    /**
     * 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
     *
     * @param run   需要执行的程序
     * @param vTime 间隔时间
     * @return 执行标志
     */
    public static String setInterval(Runnable run, int vTime) {
        return interval.set(run, vTime);
    }

    /**
     * 清除需要执行的任务
     *
     * @param flag 执行标志
     */
    public static void clearInterval(String flag) {
        interval.remove(flag);
    }

    /**
     * 清除需要执行的任务
     *
     * @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
     */
    public static void clearInterval(Runnable run) {
        interval.remove(run);
    }

    /**
     * 沉睡
     *
     * @param mills 时间(毫秒)
     */
    public static void sleep(int mills) {
        try {
            Thread.sleep(mills);
        } catch (Exception ex) {
            ExceptionHelper.handleException(ThreadHelper.class, ex, mills);
        }
    }

    /**
     * 执行对象并且处理异常
     *
     * @param run 需要执行的对象
     */
    public static void executeCatch(Runnable run) {
        try {
            run.run();
        } catch (Exception ex) {
            ExceptionHelper.handleException(ThreadHelper.class, ex, null);
        }
    }

    /**
     * 需要执行的线程
     *
     * @param run
     */
    public static void runThread(final Runnable run) {
        executeService.execute(new Runnable() {
            @Override
            public void run() {
                executeCatch(run);
            }
        });
    }

    /**
     * 循环执行事务,直到停止执行
     *
     * @param run
     */
    public static void runThread(final RunInterval run) {
        runThread(new Runnable() {
            @Override
            public void run() {
                while (!run.isBreakFlag()) {
                    try {
                        run.getCode().run();
                    } catch (Exception ex) {
                        ExceptionHelper.handleException(ThreadHelper.class, ex);
                    }
                    sleep(run.getTime());
                }
            }
        });
    }

}