JAVA中的多线程之定时器&&一些面试题

定时器:

定时器是一种控制任务延时调用,或者周期调用的技术

作用:闹钟、定时邮件发送。

定时器的实现方式一:Timer 

1f63792d04254fb69486d6776217c10f.png

Timer定时器的特点和存在的问题:

1、Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入

2、可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行 

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class 多线程_6定时器 {
    public static void main(String[] args) {
        //创建Timer定时器
        Timer timer=new Timer();
        //调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行一次"+new Date());
            }
        },3000,2000);//3秒后执行,隔2秒执行一次

//        timer.schedule(new TimerTask() {
//            @Override
//            public void run() {
//                System.out.println(Thread.currentThread().getName()+"a执行");
//                //如果其中一个任务处理时间过长,会导致后续任务无法执行,后续任务需要等这个任务完成才能执行
                try {
                    Thread.sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
//                //如果其中一个定时器出现bug崩掉,会导致所有定时器崩掉
//               // System.out.println(10/0);
//            }
//        },0,2000);
//        timer.schedule(new TimerTask() {
//            @Override
//            public void run() {
//                System.out.println(Thread.currentThread().getName()+"b执行");
//            }
//        },0,2000);
    }
}

 22e63f46cf0f4f24889970ab470ebc6f.png

定时器的实现方式二: ScheduledExecutorService

045fb54a94ab40839ebf92d90ab09aba.png

ScheduledExecutorService的优点:

基于线程池,某个任务的执行情况不会影响其他定时任务的执行 

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ses{
    public static void main(String[] args) {
        //创建ScheduledExecutorService线程池,做定时器
        //固定线程数量的线程池
        ScheduledExecutorService pool= Executors.newScheduledThreadPool(3);//只有3个线程,最大也只有3个线程,超出也不会创建临时线程
        //开启定时任务
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"输出:A\t"+new Date());
                //当其中一个任务处理时间过长时,也不会影响其他任务的进行
                try {
                    Thread.sleep(10000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },3,2, TimeUnit.SECONDS);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"输出:B\t"+new Date());
                //如果其中一个定时器出现bug崩掉,也不会导致所有定时器崩掉
                System.out.println(10/0);
            }
        },3,2,TimeUnit.SECONDS);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"输出:C\t"+new Date());
            }
        },3,2,TimeUnit.SECONDS);
    }
}

可能会遇到的面试题:

1、并发与并行:

正在运行的程序(软件)就是一个独立的进程,线程是属于进程的,多个线程其实是并发与并行同时进行的。

1.1、并发的理解:

CPU同时处理线程的数量有限

CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。 

1.2、并行的理解:

在同一个时刻上,同时有多个线程在被CPU处理并执行。

2、线程生命周期中的6种状态:

NEW(新建):线程刚被创建,但是并未被启动

Runnable(可运行):线程已经调用了start()等待CPU调度

Blocked(锁堵塞):线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态。

Waiting(无线等待):一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒。

Timed Waiting(计时等待):同Waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。带有超时参数的常用方法有Thread.sleep、Object.wait。

Teminated(被终止):因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

猜你喜欢

转载自blog.csdn.net/qq_62731133/article/details/124482438