在kafka server中会启动KafkaScheduler
kafka-trunk\core\src\main\scala\kafka\server\KafkaServer.scala
#这里的形参表示thread的个数
kafkaScheduler = new KafkaScheduler(config.backgroundThreads)
kafkaScheduler.startup()
这里首先new 一个KafkaScheduler的类,然后调用其startup函数
kafkascheduler的实现如下:
kafka-trunk\core\src\main\scala\kafka\utils\KafkaScheduler.scala
从构造函数可以看到除了可以设置kafkascheduler支持的线程数外,还可以设置线程的name,这里名字
一般都用缺省的
class KafkaScheduler(val threads: Int,
val threadNamePrefix: String = "kafka-scheduler-",
daemon: Boolean = true) extends Scheduler with Logging {
private var executor: ScheduledThreadPoolExecutor = null
private val schedulerThreadId = new AtomicInteger(0)
override def startup() {
debug("Initializing task scheduler.")
this synchronized {
if(isStarted)
throw new IllegalStateException("This scheduler has already been started!")
#新建一个线程池
executor = new ScheduledThreadPoolExecutor(threads)
executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false)
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false)
#设置线程池的线程工厂为KafaThread
executor.setThreadFactory(new ThreadFactory() {
def newThread(runnable: Runnable): Thread =
new KafkaThread(threadNamePrefix + schedulerThreadId.getAndIncrement(), runnable, daemon)
})
}
}
kafkascheduler提供了一个scheduler来进行任务调度
def schedule(name: String, fun: () => Unit, delay: Long, period: Long, unit: TimeUnit) {
debug("Scheduling task %s with initial delay %d ms and period %d ms."
.format(name, TimeUnit.MILLISECONDS.convert(delay, unit), TimeUnit.MILLISECONDS.convert(period, unit)))
this synchronized {
ensureRunning()
#定义一个runnable 对象来执行用户需要执行的函数fun
val runnable = CoreUtils.runnable {
try {
trace("Beginning execution of scheduled task '%s'.".format(name))
fun()
} catch {
case t: Throwable => error(s"Uncaught exception in scheduled task '$name'", t)
} finally {
trace("Completed execution of scheduled task '%s'.".format(name))
}
}
#判断这个函数是否要周期运行,直接调用executor来执行用户的函数
if(period >= 0)
executor.scheduleAtFixedRate(runnable, delay, period, unit)
else
executor.schedule(runnable, delay, unit)
}
}
最后我们看下KafkaScheduler 的线程工厂的KafkaThread,可以看到这里的KafkaThread直接是才用java 语言来实现的
而前面的kafkaScheduler是scala来实现的,这里可以看出scala是直接可以调用java函数的,反之亦然.
public class KafkaThread extends Thread {
private final Logger log = LoggerFactory.getLogger(getClass());
public KafkaThread(final String name, boolean daemon) {
#可以看到最终调用父类Thread来实现线程
super(name);
configureThread(name, daemon);
}
public KafkaThread(final String name, Runnable runnable, boolean daemon) {
super(runnable, name);
configureThread(name, daemon);
}
#这个函数可以将新建的线程配置为daemon。
private void configureThread(final String name, boolean daemon) {
setDaemon(daemon);
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
log.error("Uncaught exception in thread '{}':", name, e);
}
});
}
}