JavaEE--线程池与定时器

本文详细介绍了Java中的线程池(包括核心参数、创建方式以及标准库提供的Executor接口)和定时器(如标准库的Timer类及自定义实现),重点讲解了如何利用线程池提高效率和定时器的定时任务调度。
摘要由CSDN通过智能技术生成

一.线程池

1.线程池的简要介绍及其优点

为了解决频繁创建和销毁线程带来的巨大开销问题,我们引入了线程池。线程池,简单来说就是提前把线程创建好,放到用户态代码中写的数据结构里面,需要使用的时候从池子取,用完了再放回去。使用线程池避免了直接调用api创建和销毁线程这种需要内核完成的工作,整体上都是用户态代码,在很大程度上提高了效率。

2.线程池参数

corePoolSize:核心线程数 (线程池最少线程数)

maximumPoolSize:最大线程数 (线程池最大线程数)

keepAliveTime:非核心线程允许空闲的最大时间 (在该时间内没有任务执行,就被回收)   (非核心线程数+核心线程数=最大线程数)

unit:keepAliveTime参数的时间单位

workQueue:线程池的任务队列 (线程池提供submit方法,让其他线程把任务交给线程池,该队列把要执行的任务保存起来,以便后续线程池内部的工作线程消费这个队列,从而完成具体的任务执行)

threadFactory:线程工厂,把线程的属性提前初始化

handler:拒绝策略,总共分为四种

1)AbortPolicy:直接抛出异常

2)CallerRunsPolicy:谁负责添加任务,谁去负责执行任务

3)DiscardOldestPolicy:丢弃最老的任务,让新的任务去队列中派对

4)DiscardPolicy:丢弃最新的任务

3.线程池的创建

3.1 标准库中的线程池

1.标准库中提供了使用Executor创建线程池的几种方式:

(1) newFixedThreadPool:创建固定线程数目的线程池

(2) newCachedThreadPool:创建一个能够根据任务数目自动进行线程扩容的线程池

(3) newSingleThreadPoolExecutor:创建一个只包含单个线程的线程池

(4) newScheduledThreadPool:创建一个固定线程个数,但是任务延迟执行的线程池

3.2 简单实现线程池

一个线程池要包含的东西:1)有若干个线程  2)有任务队列  3)提供submit方法

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Thread_pool {
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    public Thread_pool(int n) {//初始化线程池,固定线程数
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }

    public void submit(Runnable runnable) throws InterruptedException {//把任务添加到线程中
        queue.put(runnable);
    }
}

二.定时器 

1.定时器的简要介绍

定时器,简单来说就是一个“闹钟”,达到一个设定的时间之后,就执行指定好的代码

2.定时器的创建

2.1 标准库中的定时器

标准库中提供了Timer类用于创建定时器,Timer类的核心方法为schedule方法,该方法包含两个参数,第一个参数指定要执行的任务,第二个参数指定多长时间之后执行

import java.util.Timer;
import java.util.TimerTask;

public class timer_test {
    public static void main(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        },2000);
        timer.schedule(new TimerTask() {//可以安排多个任务
            @Override
            public void run() {
                System.out.println("hello");
            }
        },3000);
    }
}

2.2 简单实现定时器

一个定时器需要的东西:1) 定义一个类,表示一个任务 2) 通过一定的数据结构保存多个任务 3)有一个线程来负责执行任务

import java.util.PriorityQueue;

class MyTimerTask implements Comparable<MyTimerTask> {
    private Runnable runnable;
    private long time;

    public MyTimerTask(Runnable runnable, long delay) {
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

    public void run() {
        runnable.run();
    }

    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int) (this.time - o.time);
    }
}

public class MyTimer {

    private PriorityQueue<MyTimerTask> taskQueue = new PriorityQueue<>();
    private Object locker = new Object();

    public MyTimer() {
        //这个线程负责不停扫描上述队列的首元素来确定是否要执行任务
        Thread t = new Thread(() -> {
            try {
                while (true) {
                    synchronized (locker) {
                        if (taskQueue.size() == 0) {
                            locker.wait();
                        }
                        MyTimerTask task = taskQueue.peek();
                        long curTime = System.currentTimeMillis();
                        if (curTime >= task.getTime()) {//时间到了要执行任务
                            task.run();
                            taskQueue.poll();
                        } else {//时间没到
                            locker.wait(task.getTime() - curTime);
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
    }

    public void schedule(Runnable runnable, long delay) {
        synchronized (locker) {
            MyTimerTask task = new MyTimerTask(runnable, delay);
            taskQueue.offer(task);
            locker.notify();
        }
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaEE-图书管理系统通常需要包含以下数据库表: 1. 用户表(user):包括用户ID、用户名、密码、邮箱等字段。 2. 图书表(book):包括图书ID、图书名称、作者、出版社、ISBN号等字段。 3. 借阅记录表(borrow_record):包括借阅记录ID、用户ID、图书ID、借阅时间、归还时间等字段。 4. 管理员表(admin):包括管理员ID、管理员名称、密码等字段。 以下是JavaEE-图书管理系统数据库代码示例: ```sql -- 用户表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, `email` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 图书表 CREATE TABLE `book` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `author` varchar(50) NOT NULL, `publisher` varchar(50) NOT NULL, `isbn` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 借阅记录表 CREATE TABLE `borrow_record` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `book_id` int(11) NOT NULL, `borrow_time` datetime NOT NULL, `return_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_user_id_idx` (`user_id`), KEY `fk_book_id_idx` (`book_id`), CONSTRAINT `fk_book_id` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 管理员表 CREATE TABLE `admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` -- 相关问题--: 1. 如何创建数据库表? 2. 如何在JavaEE中连接数据库? 3. 数据库中的什么是外键?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值