再谈线程

Why Thread

在没有线程的从前日子,当服务器处理成千上万个连接的时候性能问题就非常突兀了,这个时候

  • 重用进程
  • 使用轻量级的线程
    书中提到使用线程代替进程会使服务器性能提升三倍,如果再使用线程池可以提升九倍多。
    使用线程池处理短连接可以在每分钟使用100个不到线程处理数千个短连接。
  • 异步I/O
    在IM的应用场景中经常会出现同时需要数千个很长时间的连接。
    这个会在以后的文章中详细讲解。

    再谈实现线程的两种方式

    在上一篇文章中我们详细分析了new Threadimplements Runnable的区别,在本书中再次涉及这两种方式。
    一般选择Runnable因为这种方式可以更清楚的将线程要完成的任务与线程本身区分开。
    另外在继承Thread类的时候要注意,仅覆盖run方法,其他方法都有其特殊的语义,且其在虚拟机中的交互很难在你的代码中重新实现。
    然而并不认为Runnable接口就一定优于继承Thread类,因为在某些场景下需要在每个Thread对象的构造函数中调用Thread类的一些实例方法,这种情况就继承就很有用。

    从线程中返回信息

    run()start()并不返回任何值。那么该如何获得。看下下面这张图。

    同步

    当两个线程同时访问同一个资源时候,其中一个必须等待另个结束。这里就需要同步。
    看下下面这张图

同步锁住资源的同时也会导致一个问题:死锁
要防止死锁,最主要的还是要避免不必要的同步(同步应该是保证线程安全的最后一道防线),这个在前面的文章里也讲过很多方法。建议参考《Java并发编程》

线程调度

现在我们已经通过Thread或者Runnable方式获得了多个线程,那么该如何保证其中的线程按照你想要的顺序执行呢。
看下面这张图能大致了解。

参考资料

《Java网络编程》第三章