java-线程池(ScheduledExecutorService)

先回顾一下,Runnable 的使用方法。

package demo.knowledgepoints.scheduledtask.run;

/***
* 线程类
*/
public class ThreadTest implements Runnable {

public static int ticket = 9;

@Override
public void run() {
try {
System.out.println("当前线程:"+Thread.currentThread().getName());
while(true){
synchronized (this) {
Thread.sleep(1000L);
if (this.ticket > 0) {
ticket--;
System.out.println(Thread.currentThread().getName() + ":出售一张票!");
System.out.println("剩余票量:" + ticket);
} else {
System.out.println("没有票了!");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

 

package demo.knowledgepoints.scheduledtask.run;

public class ThreadMemo {
    public static void main(String[] args) {
        ThreadTest threadTest1 =new ThreadTest();
        new Thread(threadTest1).start();
        new Thread(threadTest1).start();
    }
}

每一个线程的启动,都会占用资源,一个线程5分钟执行一次,一个线程10分钟执行。两个线程分别启动则需要启动两个线程。线程越多需要启动的线程就越多。性能浪费就越大。

于是我们会考虑,5分钟的线程,我们5分钟到了去唤醒一个线程,执行一次,然后再让其睡眠,10分钟的线程也如初,就可以省下同一时间的线程数,线程越多效果越是明显。

正好:java提供了方法:ScheduledExecutorService

我们就根据ScheduledExecutorService来实现一个线程池:

package demo.knowledgepoints.scheduledtask.inf;

import demo.knowledgepoints.scheduledtask.iml.ScheduledTaskTot;

public interface ScheduledService {

    /**
     * 添加一个任务
     * @author Eric
     * @date 16:14 2019/3/12
     * @params runnable
     * @params taskId
     * @params initialDelay 初次等待 毫秒
     * @params delay 间隔时间 毫秒(不延迟)
     * @throws
     * @return boolean
     **/
    boolean addFixedTask(ScheduledTaskTot scheduledTaskTot);

    /**
     * 添加一个任务
     * @author Eric
     * @date 16:14 2019/3/12
     * @params runnable
     * @params taskId
     * @params initialDelay 初次等待 毫秒
     * @params delay 间隔时间 毫秒(延迟)
     * @throws
     * @return boolean
     **/
    boolean addTask(ScheduledTaskTot scheduledTaskTot);

    /**
     * 修改一个任务
     * @author Eric
     * @date 16:14 2019/3/12
     * @params runnable
     * @params taskId
     * @params initialDelay 初次等待 毫秒
     * @params delay 间隔时间 毫秒
     * @throws
     * @return boolean
     **/
    boolean updateTask(ScheduledTaskTot scheduledTaskTot) throws InterruptedException;

    /**
     * 移除一个任务
     * @author Eric
     * @date 16:14 2019/3/12
     * @params taskId
     * @throws
     * @return boolean
     **/
    boolean remove(String taskId);

    /**
     * 关闭定时任务服务
     * @author Eric
     * @date 16:14 2019/3/12
     * @throws
     * @return void
     **/
    void shutdown();

    /**
     * 初始化定时任务服务
     * @author Eric
     * @date 16:15 2019/3/12
     * @throws
     * @return void
     **/
    void init() throws Exception;
}
package demo.knowledgepoints.scheduledtask.inf;

public interface TaskServcesInf {

    public void Test1();
    public void Test2();
    public void Test3();
}
package demo.knowledgepoints.scheduledtask.iml;

import demo.knowledgepoints.scheduledtask.inf.ScheduledService;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ScheduledServiceIml implements ScheduledService {

    private static ScheduledExecutorService service;


    private static Map<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>();

    @Override
    public boolean addFixedTask(ScheduledTaskTot scheduledTaskTot) {
        if (futureMap.get(scheduledTaskTot.getTaskId()) != null) {
            return false;
        }
        // 这里将任务放入定时服务中
        ScheduledFuture<?> scheduledFuture = service.scheduleAtFixedRate(scheduledTaskTot.getRunnable()
                , scheduledTaskTot.getInitialDelay(), scheduledTaskTot.getDelay(), TimeUnit.MILLISECONDS);

        futureMap.put(scheduledTaskTot.getTaskId(),scheduledFuture);
        return true;
    }

    @Override
    public boolean addTask(ScheduledTaskTot scheduledTaskTot) {
        if (futureMap.get(scheduledTaskTot.getTaskId()) != null) {
            return false;
        }
        // 这里将任务放入定时服务中
        ScheduledFuture<?> scheduledFuture = service.scheduleWithFixedDelay(scheduledTaskTot.getRunnable()
                , scheduledTaskTot.getInitialDelay(), scheduledTaskTot.getDelay(), TimeUnit.MILLISECONDS);

        futureMap.put(scheduledTaskTot.getTaskId(),scheduledFuture);

        return true;
    }

    @Override
    public boolean updateTask(ScheduledTaskTot scheduledTaskTot) throws InterruptedException {
        if (futureMap.get(scheduledTaskTot.getTaskId()) == null) {
            return false;
        }
        // 先停止
        remove(scheduledTaskTot.getTaskId());

        // 再添加
        addTask(scheduledTaskTot);
        return true;
    }

    @Override
    public boolean remove(String taskId) {
        if (futureMap.get(taskId) == null) {
            return false;
        }
        ScheduledFuture scheduledFuture = futureMap.get(taskId);
        scheduledFuture.cancel(false);
        futureMap.remove(taskId);
        return true;
    }

    @Override
    public void shutdown() {
        service.shutdown();
    }

    @Override
    public void init() throws Exception {
        service = Executors.newScheduledThreadPool(8);
    }
}
package demo.knowledgepoints.scheduledtask.iml;

import demo.untils.StringUntil;
import demo.untils.TimeUtil;

import java.lang.reflect.Method;

public class ScheduledTaskTot {

    /** 需要执行方法的线程 */
    Runnable runnable;
    /** 唯一的id用于增删改 */
    String taskId;
    /** 定时任务需要执行的方法类 */
    String className;
    /** 定时任务需要执行的方法 */
    String method;
    /** 首次执行等待时间 */
    long initialDelay;
    /** 间隔时间 */
    long delay;

    /**
     * 创建一个需要定时的任务
     * @param taskId
     * @param className
     * @param method
     * @param initialDelay
     * @param delay
     * @param beginTime(执行开始时间)
     * @param endTime(执行结束时间)
     */
    public ScheduledTaskTot(String taskId, String className, String method, long initialDelay, long delay, String beginTime, String endTime) {
        this.taskId = taskId;
        this.className = className;
        this.method = method;
        this.initialDelay = initialDelay;
        this.delay = delay;
        // 在创建实例的时候,初始化线程类,通过反射获取要执行的类与方法,目前没有加参数,大家可以自行扩展
        runnable = () -> {
            System.out.println("---------------------------------");
            try {
                //在beginTime 到 endTime 之间才执行。
                if(StringUntil.isNotBlank(beginTime) && StringUntil.isNotBlank(endTime)){
                    if(TimeUtil.getTimeMillis(beginTime) - System.currentTimeMillis() >= 0 && TimeUtil.getTimeMillis(endTime) - System.currentTimeMillis() <= 0){
                        Class<?> cls = Class.forName(className);
                        Method method1 = cls.getMethod(method);
                        method1.invoke(cls.newInstance(),null);
                    }
                }else{
                    Class<?> cls = Class.forName(className);
                    Method method1 = cls.getMethod(method);
                    method1.invoke(cls.newInstance(),null);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }

    public Runnable getRunnable() {
        return runnable;
    }

    public void setRunnable(Runnable runnable) {
        this.runnable = runnable;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public long getInitialDelay() {
        return initialDelay;
    }

    public void setInitialDelay(long initialDelay) {
        this.initialDelay = initialDelay;
    }

    public long getDelay() {
        return delay;
    }

    public void setDelay(long delay) {
        this.delay = delay;
    }
}
package demo.knowledgepoints.scheduledtask.iml;

import demo.knowledgepoints.scheduledtask.inf.TaskServcesInf;

public class TaskServcesIml implements TaskServcesInf {

    public void Test1(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Test1------------------------");
    }
    public void Test2(){
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Test2------------------------");
    }

    public void Test3(){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Test3------------------------");
    }
}
package demo.knowledgepoints.scheduledtask.iml;

public class ScheduledServiceTest {

    public static void main(String[] args) {
        ScheduledServiceIml scheduledServiceIml = new ScheduledServiceIml();
        try {
            scheduledServiceIml.init();
            scheduledServiceIml.addTask(new ScheduledTaskTot("T0001","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test1",1000L,5000L,null,null));
            scheduledServiceIml.addTask(new ScheduledTaskTot("T0002","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test2",1000L,5000L,null,null));
            scheduledServiceIml.addTask(new ScheduledTaskTot("T0003","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test3",1000L,5000L,null,null));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 输出结果:

参考资料:https://blog.csdn.net/money9sun/article/details/88575704?tdsourcetag=s_pctim_aiomsg

如有疑问请留言,每一个都会及时回复。




转载于:https://www.cnblogs.com/jssj/p/10989425.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值