0
点赞
收藏
分享

微信扫一扫

Day30.守护线程、定时器

守护线程

  • Java语言中线程分为两大类:

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

注意:主线程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();
            }
        }
    }
}

定时器

  • 定时器的作用:

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

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

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

  • 构造方法
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新特性)

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

  • 实现Callble接口:
    优点:这种方式实现的线程可以获取线程的返回值
    缺点:这种方式执行效率较低,在获取线程执行结果时,当前线程会受到阻塞。

/*实现线程的第三种方式:
    实现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类方法
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)
          试图取消对此任务的执行。

举报

相关推荐

0 条评论