本文从三方面展开:
- 并发有什么好处
- 并发带来的问题
- 这些问题如何解决
文末附 synchronized、volatile 关键字解析,其他并发包下内容,请参考后续文章。
1. 并发有什么好处
并发可以充分利用CPU资源,降低系统响应时间,提升系统吞吐量。
并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律成为计算机性能发展源动力的根本原因,也是人类“压榨”计算机运算能力的最有力武器。 —— 引自《深入理解Java虚拟机》
本文从三方面展开:
文末附 synchronized、volatile 关键字解析,其他并发包下内容,请参考后续文章。
并发可以充分利用CPU资源,降低系统响应时间,提升系统吞吐量。
并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律成为计算机性能发展源动力的根本原因,也是人类“压榨”计算机运算能力的最有力武器。 —— 引自《深入理解Java虚拟机》
Compare-and-Swap 或者 Compare-and-Set 简称 CAS。
CAS操作是原子性的,CAS指令需要有三个操作数,分别是内存位置(在Java中可以简单地理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和准备设置的新值(用B表示)。CAS指令执行时,当且仅当V符合A时,处理器才会用B更新V的值,否则它就不执行更新。
在 JDK 5之后,Java类库中才开始使用CAS操作,该操作由sun.misc.Unsafe
类里面的compareAndSwapInt()
和compareAndSwapLong()
等几个方法包装提供。HotSpot
虚拟机在内部对这些方法做了特殊处理,即时编译出来的结果就是一条平台相关的处理器CAS指令,没有方法调用的过程,或者可以认为是无条件内联进去了。不过由于Unsafe类在设计上就不是提供给用户程序调用的类【Unsafe::getUnsafe()
的代码中限制了只有启动类加载器(Bootstrap ClassLoader
)加载的Class才能访问它】,因此在JDK 9
之前只有Java类库可以使用CAS,譬如J.U.C
包里面的整数原子类,其中的compareAndSet()
和getAndIncrement()
等方法都使用了Unsafe类的CAS操作来实现。而如果用户程序也有使用CAS操作的需求,那要么就采用反射手段突破Unsafe
的访问限制,要么就只能通过Java类库API来间接使用它。直到JDK 9
之后,Java类库才在VarHandle
类里开放了面向用户程序使用的CAS
操作。
import com.google.common.util.concurrent.ThreadFactoryBuilder;
public class ThreadFactoryTest {
public static void main(String [] args) {
// 创建线程工厂,并设置线程名字格式
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build();
// if (corePoolSize > maximumPoolSize) throw IllegalArgumentException(非法调度Exception)
ExecutorService singleThreadPool = new ThreadPoolExecutor(12, 24,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy());
singleThreadPool.execute(() -> System.out.println(Thread.currentThread().getName()));
singleThreadPool.shutdown();
}
}