- TaskRunner类的位置:package org.apache.hadoop.yarn.sls.scheduler;
- TaskRunner类概览:
分析:该类由一个静态类Task和几个方法和变量组成。其中静态嵌套抽象类Task实现了Runnable和Delayed接口。
其中的变量包括DelayQueue queue和ThreadPoolExecutor executor等。
有哪些类继承了这个静态嵌套抽象类TaskRunner.Task了呢?- AMSimulator
- NMSimulator
- TaskRunner.Task内部的类变量 private Queue<\Task> queue使用了。TaskRunner.Task的结构图如下:
可以看出:RM没有simulator,实际上sls使用的是yarn里的ResourceManager类。
需要注意的是:run()方法是final的,不能被子类重写(见下面的代码)。firstStep(),middleStep(),lastStep()都是抽象的方法,需要被重写。
也就是说,如果该类的子类被用来new线程,且执行了start()方法,那么就会执行该类的run()方法,来调用子类重写的firstStep(),middleStep(),lastStep()方法。
@Override
public final void run() {
try {
if (nextRun == startTime) {
firstStep();
nextRun += repeatInterval;
if (nextRun <= endTime) {
queue.add(this);
}
} else if (nextRun < endTime) {
middleStep();
nextRun += repeatInterval;
queue.add(this);
} else {
lastStep();
}
} catch (Exception e) {
e.printStackTrace();
Thread.getDefaultUncaughtExceptionHandler()
.uncaughtException(Thread.currentThread(), e);
}
}
public abstract void firstStep() throws Exception;
public abstract void middleStep() throws Exception;
public abstract void lastStep() throws Exception;
- 基础知识补充:
静态内部类:
根据Oracle官方的说法:Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.从字面上看,一个被称为静态嵌套类,一个被称为内部类。从字面的角度解释是这样的:什么是嵌套?嵌套就是我跟你没关系,自己可以完全独立存在,但是我就想借你的壳用一下,来隐藏一下我自己(真TM猥琐)。什么是内部?内部就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的)至于具体的使用场景,我就不当翻译工了,有兴趣的直接去官网看吧。传送门:http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
作者:昭言 链接:https://www.zhihu.com/question/28197253/answer/39814613 来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
DelayQueue:
DelayQueue是一个无界的BlockingQueue,用于防止实现了Delayed接口的对象,其中的对象只能在器到期是才能从队列中取走。这种队列是有序的,即队头对象的延迟到期的时间最长。如果没有任何延迟到期,那么就不会有任何头元素,并且poll())将返回null.(正因为这样,你不能将null放置到这种队列中。)
Delayed扩展了Comparable接口,比较的基准为延时的时间值,Delayed接口的实现类getDelay的返回值应为固定值(final)。DelayQueue内部是使用PriorityQueue实现的。DelayQueue = BlockingQueue + PriorityQueue + Delayed
DelayQueue的关键元素BlockingQueue、PriorityQueue、Delayed。可以这么说,DelayQueue是一个使用优先队列(PriorityQueue)实现的BlockingQueue,优先队列的比较基准值是时间。
转自:https://www.cnblogs.com/jobs/archive/2007/04/27/730255.html
BlockingQueue(阻塞队列):
抽象类:
例子:
public abstract static class Task implements Runnable, Delayed {
private long start;
private long end;
private long nextRun;
private long startTime;
private long endTime;
private long repeatInterval;
private Queue<Task> queue;
public Task(){}
public void init(long startTime) {//抽象类可以有实现了的方法。
init(startTime, startTime, 1);
}
public void setEndTime(long et) {
endTime = et;
}
private void timeRebase(long now) {//抽象类可以有私有方法和私有变量
startTime = now + start;
endTime = now + end;
this.nextRun = startTime;
}
private void setQueue(Queue<Task> queue) {
this.queue = queue;
}
public abstract void firstStep() throws Exception;//抽象方法是没有方法体的!!
public abstract void middleStep() throws Exception;
public abstract void lastStep() throws Exception;
}
java提供体格叫做抽象方法的机制。这种方法是不完整的;仅有声明而没有方法体。下面抽象方法声明所采用的语法:abstract void f();
包含抽象方法的类称为抽象类,如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。(否则编译器会报错。)注意:不要求所有的方法都是abstract型。
Java 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
.
Java抽象类不可以被 final修饰。因为抽象类需要被继承才能使用,而被final修饰的类无法被继承,所以abstract和final是 不能共存的。
Java抽象类是内部类时,可以被private修饰;不是内部类时,不可以被private修饰
.
Java抽象类不能直接生成对象。
.
.
如果子类不是抽象类就必须实现父类的所有abstract 方法。
.
抽象类可以没有抽象方法,这时的抽象类和普通类的最大差别就是不能实例化.如jdk中IO包的FilterReader类,这里的FilterReader其实起了一种强制子类类型化(FilterReader)的作用.参考:https://blog.csdn.net/gxnu/article/details/1766044
.
Java允许抽象类中有private变量和private方法,因为按照抽象类的定义,抽象类与一般类的不同之外只在于它里面含有抽象的方法(也可能没有)。既然一般类中有private变量和private方法,抽象类中也能有。大家写一个抽象类就都明白了。
需要注意的是,抽象类中的abstract方法不能为private,因为它需要子类来继承它。参考:https://bbs.csdn.net/topics/90369102中vcokno1的答案。
.
好处:创建抽象类和抽象方法非常有用,因为他们可以类的抽象性明确起来,并告诉用户和编译器打算怎么来使用他们。抽象类还是很有用的重构工具,因为他们使得我们可以很容易的将公共方法沿着继承层次结构向上移动。