第三章:函数式编程

1.概要

函数式编程——将计算过程抽象成表达式求值。这些表达式由纯数学函数构成,这些数学函数式第一类对象(我们可以像操作数值一样操作第一类对象)并且没有副作用。函数式编程可以更容易做到线程安全,因此特别适合并发编程。之前Java中提到的锁就是为了应对共享的可变状态,但是函数式编程没有可变状态,所以不会遇到由共享可变状态带来的种种问题。

2.可变状态的风险——隐藏和逃逸

我们来回顾一下Java语言中可变状态的问题

2.1 隐藏的可变状态

即使你以为你自己写了一段不存在可变状态的代码,但是仍然可能由于使用 了Java的某些类,使得其在多线程环境是线程非安全的。

2.2......

第二章:线程与锁(站在巨人肩膀上)

1. 概览

这一小节内容之所取名站在巨人肩膀上,是告诉我们要善用那些已经有大牛写好的工具。当然我们这里说的还是java

2.创建线程

在服务器上,每个请求有一个对应的处理线程,如果使用普通创建线程的方法,会有以下问题:

不断的创建和销毁线程存在代价

当请求链接的速度高于处理链接的速度时,线程数量会不断增长,导致服务器停止服务而崩溃。这给那些相对服务器进行拒绝服务供给的人提供了可乘之机。

可以采用Executors里面的方法来创建线程池

线程池设置多大的一般性准则:对于CPU密集型的任务,线程大小应该接近于核数;对于IO密集型任务,线程池可以设置的大一些。......

第二章:线程与锁(超越内置锁)

1.内置锁的弊端

内置锁的使用:

synchronized(object){

//使用共享资源

}

内置锁虽然方便但是又很多限制:

一个线程因为等待内置锁而进入阻塞之后,就无法终端该线程

尝试获取内置锁时,无法设置超时

获得内置锁,必须使用synchronized块

2. ReentrantLock

超越内置锁就是靠ReentrantLock替代synchronized工作,弥补内置锁的问题。用法如下:

Lock lock = new ReentrantLock();

lock.lock();

try{

//使用共享资源

} finally{

lock......