Java中使用匿名内部类开启线程的实现方式、线程池、定时器


前言

通过本文,首先重新明确线程中存在的五种状态,其次使用之前按所学匿名内部类的知识来实现线程,然后介绍多线程中线程池的概念并结合代码介绍三种线程池实现的方式,最后了解多线程中定时器的概念并结合两段代码带大家了解定时器的使用。

一、线程的状态

  • 五种状态
  1. 新建:线程被创建出来
  2. 就绪:具有CPU 的执行资格,但不具有CPU的执行权
  3. 运行:具有CPU 的执行资格,具有CPU的执行权
  4. 阻塞:不具有CPU 的执行资格,也不具有CPU的执行权
  5. 死亡:不具有CPU 的执行资格,也不具有CPU的执行权
  • 线程运行状态图
    在这里插入图片描述

二、使用匿名内部类开启线程

1.实现方式1

  • 基本代码
 new Thread(){
            @Override
            public void run() {
                System.out.println("线程1执行了");
            }
        }.start();
  • 调用有参构造传名字
new Thread("线程2"){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行了");
            }
        }.start();

2.实现方式2

  • 基本代码
new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程3执行了");
            }
        }).start();
  • 调用有参构造传名字
new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行了");
            }
        },"线程4").start();

三、线程池的概念及实现方式

1.线程池的概念

  • 程序启动一个新线程成本是比较高的,因为它设计到要与操作系统进行交互。而使用线程池可以更好的提供性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池
  • 线程池其实就是一个容器,可以帮我们创建一定数量的线程对象
  • 线程池里的每个线程代码结束后,不会死亡,而是回到线程池中称为空闲状态,等待下一个对象使用

2.实现线程池的3种方式

  • 在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池。
  • JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法。
1.线程池的实现方式一
  • public static ExecutorService newCachedThreadPool()
    根据任务的数量来创建线程对应的线程个数 (任务数=线程数)
  • 代码:
public class 线程池实现方式1 {
    public static void main(String[] args) {
        //通过工厂类,获取线程池对象
        ExecutorService executorService = Executors.newCachedThreadPool();
        //给线程池中提交任务(根据任务数量,创建线程个数)
        //创建了3个线程完成3个任务
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println(Thread.currentThread().getName() +"执行任务1");
                }

            }
        });

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println(Thread.currentThread().getName()+"执行任务2");
                }

            }
        });

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println(Thread.currentThread().getName() + "执行任务3");
                }

            }
        });
        //关闭线程池
        executorService.shutdown();

    }

}
2.线程池的实现方式二
  • public static ExecutorService newFixedThreadPool(int nThreads)
    固定初始化指定线程个数 (线程数任意指定)
  • 代码
public class 线程池的实现方式2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //固定初始化3个线程
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        //可以传递callable任务,可以获得线程执行完后的结果
        Future<Integer> future =executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("线程执行了");
                return 100;
            }
        });
        //获取线程执行结果的返回值
        Integer integer = future.get();
        System.out.println(integer);

    }
}
3.线程池的实现方式三
  • public static ExecutorService newSingleThreadExecutor()
    初始化一个线程的线程池 (线程个数为1)
  • 代码:
public class 线程池的实现方式3 {
    public static void main(String[] args) {
        //初始化一个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行了任务1");
            }
        });
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行了任务2");
            }
        });
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行了任务3");
            }
        });
        //注意:该三个任务都是由一个线程完成的

    }
}

四、定时器

  • 定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台的方式执行。

  • 在Java中,可以使用 Time类TimeTask类 来实现定义调度的功能。

  • Timer:

    • public Timer()
    • public void schedule(TimerTask task, long delay):
    • public void schedule(TimerTask task,long delay,long period);
    • public void schedule(TimerTask task, Date time):
    • public void schedule(TimerTask task, Date firstTime, long period):
  • TimerTask:定时任务

    • public abstract void run()
    • public boolean cancel()

代码示例1:

public class 定时器 {
    public static void main(String[] args) {
        //timer类,是一种工具,线程用其安排以后在后台线程中执行的任务,可以安排任务执行一次,或者定期重复执行。
        Timer t1 = new Timer();
        //等待多少毫秒之后,执行定时任务
        TimerTask task=new TimerTask() {
            @Override
            public void run() {
                System.out.println("爆炸");
            }
        };
        //任务等待5秒执行,1秒不间断执行一次
        t1.schedule(task,1000*5,1000);
        //取消定时器
        //t1.cancel();
        //取消任务
        //task.cancel();
    }
}

代码示例2:

public class 定时器2 {
    public static void main(String[] args) throws ParseException {
        Timer timer = new Timer();
        String dateStr="2021-01-23 13:00:00";
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
        //使用匿名内部类创建TimeTask
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("从今日起,每日13:00疫情填报");
            }
        },date,1000*60*60*24);

    }
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页