其他分享
首页 > 其他分享> > Day30.守护线程、定时器

Day30.守护线程、定时器

作者:互联网

守护线程

一类是:用户线程; 一类是:守护线程(后台线程);

注意:主线程main方法是一个用户线程

守护线程中最具有代表性的就是:垃圾回收线程

守护线程一般是一个死循环,所有的用户线程只要结束,守护线程自动结束

如:每天24点时,系统数据自动备份

这个需要使用到定时器,我们可以将定时器设置为守护线程。

如果结束了,守护线程自动退出,没有必要进行数据备份了。

 voidsetDaemon(boolean on)
          将该线程标记为守护线程或用户线程。
/*守护线程*/
public class ThreadTest11 {
    public static void main(String[] args){
        Thread t = new BakDataThread();
        t.setName("备份数据的线程");

        //启动线程之前,将线程设置为守护线程
        t.setDaemon(true);
        t.start();

        //主线程:用户线程
        for(int i = 0; i<10 ;i++){
            System.out.println(Thread.currentThread().getName() + "--->"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class BakDataThread extends Thread{
    public void run(){
        int i = 0;
        while (true){
            System.out.println(Thread.currentThread().getName() + "--->" + (++i));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

定时器

间隔特定的时间,执行特定的程序。

每周尽心银行账户的总账操作;每天进行数据的备份操作;

在实际开发中,这种需求很常见。

在java中,定时器可以使用多种方式实现

使用sleep方法,设置睡眠时间,到某个时间点醒来,执行任务。这种方式是最原始的定时器。

在java中的类库中已经写好了一个定时器:java.util.Timer,可以直接拿来用。这种方式在开发中也很少用,因为现在又很多的高级框架都是支持定时任务的。

实际开发中,使用较多的是Spring框架提供的SpringTask框架,这个框架只要进行简单的配置,就可以完成定时器任务。

Timer()
          创建一个新计时器。
Timer(boolean isDaemon)
          创建一个新计时器,可以指定其相关的线程作为守护程序运行。
Timer(String name)
          创建一个新计时器,具有指定的名称。
Timer(String name, boolean isDaemon)
          创建一个新计时器,具有指定的名称,并且可以指定作为守护程序运行。
 voidschedule(TimerTask task, Date time)
          安排在指定的时间执行指定的任务。
 voidschedule(TimerTask task, Date firstTime, long period)
          安排指定的任务在指定的时间开始进行重复的固定延迟执行
 voidschedule(TimerTask task, long delay)
          安排在指定延迟后执行指定的任务。
 voidschedule(TimerTask task, long delay, long period)
          安排指定的任务从指定的延迟后开始进行重复的固定延迟执行
 voidcancel()
          终止此计时器,丢弃所有当前已安排的任务。
 intpurge()
          从此计时器的任务队列中移除所有已取消的任务。
/*使用定时器指定定时任务*/
public class TimerTest {
    public static void main(String[] args) throws ParseException {
        //创建定时器对象
        Timer timer = new Timer();
        //Timer timer = new Timer(true); 守护线程的方式

        //第一次执行时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date firstTime = sdf.parse("2022-01-15 11:37:00");

        //指定定时任务
        //timer.schedule(定时任务,第一次执行时间,间隔多久执行一次);
        timer.schedule(new LogTimerTask(),firstTime,1000*10);
    }
}
//编写一个定时任务类:假设这是一个记录日志的定时任务
class LogTimerTask extends TimerTask{
    @Override
    public void run() {
        //编写需要执行的任务
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strTime = sdf.format(new Date());
        System.out.println(strTime+ "完成了一次数据备份!");
    }
}

实现线程的第三种方式 :实现Callble接口(JDK8新特性)

思考:系统委派一个线程去执行一个任务,该线程执行完任务之后,可能会有一个执行结果,我们怎么能拿到这个执行结果呢?

/*实现线程的第三种方式:
    实现Callable接口*/
public class ThreadTest12 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //第一步: 创建一个"未来任务类"对象 (以下使用了匿名内部类的方式)
        //参数非常重要,需要给一个Callble接口实现类对象
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception { //cal;()方法相当于run方法
                //线程执行任务,执行之后可能会有一个执行结果
                System.out.println("call method begin");
                Thread.sleep(1000*10);
                System.out.println("call method end");
                int a = 100; int b = 200;
                return a+b; //自动装箱
            }
        });
        //创建线程对象
        Thread t = new Thread(task);
        //启动线程
        t.start();
        //在主线程中,怎么获取t线程的返回结果?
        Object obj = task.get();
        //这里的程序执行必须要等待get()方法执行结束,
        //而gat方法拿到执行结果需要等task线程执行结束
        //所以线程会受阻,进入阻塞状态

    }
}
FutureTask(Callable<V> callable)
          创建一个 FutureTask,一旦运行就执行给定的 Callable。
FutureTask(Runnable runnable, V result)
          创建一个 FutureTask,一旦运行就执行给定的 Runnable,并安排成功完成时 get 返回给定的结果 。
 Vget()
          等待计算完成,然后获取其结果。
 Vget(long timeout, TimeUnit unit)
          最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。
 booleanisDone()
          如果任务已完成,则返回 true。
 booleancancel(boolean mayInterruptIfRunning)
          试图取消对此任务的执行。

标签:定时器,Day30,任务,线程,new,执行,守护
来源: https://blog.csdn.net/a111042555/article/details/122507051