定时器
定时器可以在达到一个设定的时间后,就执行某个指定好的代码
Timer类
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("run....");
}
},3000);
}
Timer类是java标准库中的定时器,其核心方法是schedule()
实现Timer类
public class Timer {
static class Task implements Comparable<Task>{
private Runnable command;
private long time;
public Task(Runnable command, long time) {
this.command = command;
this.time = time + System.currentTimeMillis();
}
public Runnable getCommand() {
return command;
}
public long getTime() {
return time;
}
public void run(){
command.run();
}
@Override
public int compareTo(Task o) {
return (int)(this.time - o.time);
}
}
PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
Object locker = new Object();
public void schedule(Runnable command,long time){
Task task = new Task(command,time);
queue.put(task);
synchronized (locker){
locker.notify();
}
}
public Timer() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Task task = queue.take();
long current = System.currentTimeMillis();
if(task.getTime() > current){
queue.put(task);
synchronized (locker){
locker.wait(task.getTime() - current);
}
}else{
task.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
});
t.start();
}
}
notify()
得加上synchronized
,不加的话可能不能及时通知到wait()
线程池
线程池可以减少每次启动、销毁线程的损耗。
- 从线程池取线程,是纯用户态操作
- 通过系统创建,涉及到内核态操作
通常认为,牵扯到内核态的操作,要比纯用户态操作更低效。内核需要处理的东西比较多,不会立刻去处理相应的任务。
ExecutorService和Executors
- ExecutorService 表示一个线程池实例
- Executors是一个工厂类,能够创建出不同风格的线程池
- ExecutorService的submit方法能够向线程池中提交若干个任务
public class Demo36 {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(10);
//此处new对象采用Executors的静态方法来创建对象,此为工厂方法
for (int i = 0; i < 100; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
});
}
}
}
除了上述使用的newFixedThreadPool()
,Executors创建线程池还有以下几种方式
newCachedThreadPool()
创建线程数亩动态增长的线程池
newSingleThreadExecutor()
创建只包含单个线程的线程池
newScheduledThreadPool()
设定延迟时间后执行命令,进阶版的Timer
ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- keepAliveTime:临时线程允许的空闲时间
- unit:keepAliveTime的时间单位
- workQueue:传递任务的阻塞队列
- threadFactory:创建线程的工厂,参与具体的创建线程工作
- RejectedExecutionHandler:拒绝策略
实现线程池
class MyThreadPool{
private BlockingQueue<Runnable> queue= new LinkedBlockingQueue<>();
public void submit(Runnable task){
try {
queue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public MyThreadPool(int threadNum) {
for (int i = 0; i < threadNum; i++) {
Thread t = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()){
try{
Runnable runnable = queue.take();
runnable.run();
}catch (InterruptedException e){
e.printStackTrace();
break;
}
}
});
t.start();
}
}
}