这个虚类是kafka.network.Acceptor和kafka.network.Processor的父类,提供了一个抽象的Sever线程。

它的有趣之处在于为子类的启动和停止提供了线程间的协作机制。

当子类的shutdown方法被调用时,子类可以得知自己被停止,在子类做了适当的处理和清理后,调用自己的shutdownComplete方法,使得对子类shutdown方法的调用从阻塞状态返回,从而使调用线程得知子类的对象已经恰当的停止。

即,在另一个线程中要关闭一个AbstractServerThread,可以执行它shutdown方法,当此方法从阻塞中返回,代表它已经恰当的关闭。

同样,对子类的awaitStartup方法调用也会阻塞,直到子类确认自己完全启动,这个方法调用才会返回。

这些功能是通过对CountdownLatch和AtomicBoolean的使用来实现的。

private[kafka] abstract class AbstractServerThread extends Runnable with Logging {

  protected val selector = Selector.open();
private val startupLatch = new CountDownLatch(1)
private val shutdownLatch = new CountDownLatch(1)
private val alive = new AtomicBoolean(false) /**
* Initiates a graceful shutdown by signaling to stop and waiting for the shutdown to complete
*/
def shutdown(): Unit = {
alive.set(false)
selector.wakeup()
shutdownLatch.await
} /**
* Wait for the thread to completely start up
*/
def awaitStartup(): Unit = startupLatch.await /**
* Record that the thread startup is complete
*/
protected def startupComplete() = {
alive.set(true)
startupLatch.countDown
} /**
* Record that the thread shutdown is complete
*/
protected def shutdownComplete() = shutdownLatch.countDown /**
* Is the server still running?
*/
protected def isRunning = alive.get /**
* Wakeup the thread for selection.
*/
def wakeup() = selector.wakeup() }

由于它代表了一个Server线程,在其内部使用了java.nio的Selector。所以在shutdown时,需要调用Selector的wakeup方法,使得对Selector的select方法的调用从阻塞中返回。 

继承它的子类必须对isRunning进行判断,来确定自己是否已经被要求关闭。以及在处理关闭请求后,调用shutdownComplete()来确认已完闭完成。

由于Acceptor和Processor的实现太长,这里写了一个例子模拟它们

private class Processor extends AbstractServerThread {
override def run() {
while(isRunning) {
println("processor is running")
//执行一些操作
Thread.sleep(1000)
}
shutdownComplete()
} }

  在工作循环中判断isRunning作为退出循环的条件。然后执行shutdownComplete, 这时对Processor 的shutdown方法的调用才会返回。

kafka.network.AbstractServerThread中的线程协作机制的更多相关文章

  1. Java中的线程协作之Condition

    一.Condition接口 1.Condition接口的常用方法介绍 /** * 已经获取到锁的线程调用该方法会进入等待状态,知道其他持有锁的线程通知(signal)等待队列中的线程或者被中断退出等待 ...

  2. Java中的线程同步机制

    一.首先为什么线程需要同步? 1.多线程安全问题的原因      A:有多线程环境      B:有共享数据      C:有多条语句操作共享数据 2. //未完待续后面会继续更新

  3. CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”

    在GPU并行编程中,一般情况下,各个处理器都需要了解其他处理器的执行状态,在各个并行副本之间进行通信和协作,这涉及到不同线程间的通信机制和并行执行线程的同步机制. 共享内存"__share_ ...

  4. Java多线程编程(4)--线程同步机制

    一.锁 1.锁的概念   线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...

  5. Java编程的逻辑 (67) - 线程的基本协作机制 (上)

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  6. Java编程的逻辑 (68) - 线程的基本协作机制 (下)

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  7. ThreadLocal,Java中特殊的线程绑定机制

    在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...

  8. 浅谈利用同步机制解决Java中的线程安全问题

    我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...

  9. Java-ThreadLocal,Java中特殊的线程绑定机制

    在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...

随机推荐

  1. 160多个android开源代码汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Pro ...

  2. 我是如何自学Android,资料分享

       我是如何自学Android,资料分享(2015 版) 已经完成,我的建议是先把这一篇看完,再看2015 版的.关于我在学习中开发的项目代码,已经发布在: 爱开发-源码搜索,集成了上万个App源码 ...

  3. iOS - 数组与字典(NSArray & NSDictionary)

    1. 数组的常用处理方式 //--------------------不可变数组 //1.数组的创建 NSString *s1 = @"zhangsan"; NSString *s ...

  4. JavaScript学习笔记(11)——HTML DOM Event对象

    w3cshool:时间参考手册:http://www.w3school.com.cn/jsref/dom_obj_event.asp

  5. dispatch_async & dispatch_sync

    Clear that! dispatch_async 是将block发送到指定线程去执行,当前线程不会等待,会继续向下执行. dispatch_sync 也是将block发送到指定的线程去执行,但是当 ...

  6. reduce + Promise 顺序执行代码

    本文地址: http://www.cnblogs.com/jasonxuli/p/4398742.html 下午的太阳晒得昏昏沉沉,和上周五一样迷糊,看一段代码半天没看明白,刚才不知不觉眯了几分钟,醒 ...

  7. A标签执行js 代码和跳转

    5.执行JS代码: <a href="javascript:js代码">内容</a> ⑥.使用js来实现空链接 写法:<a href="ja ...

  8. switch的case中不能做定义

    switch的case中不能做定义 只能给语句 error: a label can only be part of a statement and a declaration is not a st ...

  9. IIS6,IIS7 最简单的重写URL

    虽然现在很少用IIS6,今天突然要把项目搬到老的服务器上(IIS6),对项目还要重新部署一下. 主要把时间花在了对url的重写上.其实很简单,如下: IIS6 网站 → 属性 → 主目录 → 配置 → ...

  10. debian 学习记录-1 -安装

    之前装ubuntu12. 后来没有继续用,图形界面很不错,没有继续学习原因很多: · 没有基础知识支持(拷贝文件都是用鼠标拖动的) · 图形界面很好,导致没有使用命令行,安装驱动什么的都是靠鼠标点击 ...