Java随谈(四)JDK对并发的支持
Java对并发的支持
在Java诞生之时,Java设计者们就考虑了并发的问题,但受限于当时的技术和需求,只是对其进行了简单的支持。
随着时代更替(多核处理器的普及,提高了程序员对处理器的使用效率的诉求),并发成为了一个需要关注的功能点。
这里,博主将概述Java各个版本(截止到JDK8)对于并发的支持的发展,便于理解这些类、接口,为何出现,又为了解决哪些问题。
历代版本
在JDK1.4及之前
- 1.synchronized、volatile关键字
- Object的wait()、notify()、notifyAll()方法
- Thread类,以及Runnable接口
- final 不变属性以及一些不变的类,比如String
- 基础但已经不被推荐使用的集合 Vector、HashTable
在这个时期,Java对并发做的支持比较底层,需要程序员手动管理需要同步的类或对象。这种情况下,除非程序员对并发有非常深的理解,才能用好这些内容。(过于底层,不易理解,编程困难)
而且由于synchronized是重量级锁,需要经常切换线程,效率比较低。(并发效率不高)
JDK1.5
- AtomicXXX类
- Lock显式锁(Lock、ReadWriteLock、Condition等接口)
- Callable、Future接口
- Executor执行器、ExecutorService两个接口以及实现类
- 并发集合BlockingQueue、ConcurrentMap、ConcurrentHashMap、CopyOnWriteArrayList
在这个时期,Java对并发进行了大刀阔斧的改进。
新增的原子操作类型比volatile关键字更易用且高效;(简化并发编程,优化性能)
Lock显示锁不同于synchronized引入了一种新的机制;(引入一种轻量的锁)
执行器使用了线程池机制,简化并发操作。(简化并发编程)
新增的并发集合比起之前的Vector、HashTable(仅在方法上添加synchronized关键词),引入了更多机制,性能也更高。
JDK1.6
- 优化后的synchronized关键字,使用分级锁机制。
这个时期,对同步关键字进行了优化、之前只存在一种重量级锁,后引入了偏向锁、轻量级锁,减少了线程切换的次数。(从语法上优化了并发性能)
优化后的synchronized关键字性能可以和Lock媲美。
JDK7
- Fork/Join框架(分解/合并框架)
- TransferQueue接口以及实现类
- ThreadLocalRandom 支持并发随机数
- Phaser工具类 阶段性并发工具类
在这个时期,提供了使用分治技术的Fork/Join框架等。
JDK8
- XXXAdder加法器、XXXAccumulator累加器(优化后的原子类型操作)
- CompletableFuture(Future升级版本)
- StampedLock (ReadWriteLock改进版本)
- 静态commonPool(为ForkJoinPool提供了多一种选择)
- StampedLock(新增在写,读和乐观读的三种模式转化的锁)
线程运用的代码示例
JDK 1.4 synchronized + 线程类
public class Counter {
/**
* 计数器
*/
private int count = 0;
/**
* 计数器加1
*/
public synchronized void increment() {
count = count + 1;
}
/**
* 获取计数器的值
*
* @return 计数器的值
*/
public synchronized int getCount() {
return count;
}
// 多线程操作(手动创建线程)
public static void main(String[] args) throws Exception {
Counter counter = new Counter();
// 创建两个线程,分别对计数器进行1000次加1操作
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// 启动两个线程
t1.start();
t2.start();
// 等待两个线程执行完毕
t1.join();
t2.join();
// 输出线程的执行结果 2000
System.out.println(counter.getCount());
}
}
JDK 5:并发工具类(Atomic class 原子类) + 线程池
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
/**
* 使用AtomicInteger类创建计数器,初始化为0
*/
private AtomicInteger count = new AtomicInteger(0);
/**
* 计数器自增, 并返回当前值
*/
public int increment() {
return count.incrementAndGet();
}
/**
* 获取当前计数器的值
*
* @return 当前计数器的值
*/
public int getCount() {
return count.get();
}
public static void main(String[] args) throws Exception {
// 创建一个线程数量为2的线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
Counter counter = new Counter();
// 提交两个任务给线程池,每个任务都对计数器进行1000次自增操作
Future<?> f1 = executor.submit(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Future<?> f2 = executor.submit(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// 等待两个任务执行完成
f1.get();
f2.get();
// 关闭线程池
executor.shutdown();
// 打印计数器的值 2000
System.out.println(counter.getCount());
}
}
JDK 8:CompletableFuture、并行流
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.IntStream;
// 使用线程池和Atomic类
public class Counter {
public static void main(String[] args) {
// 例子1 使用CompletableFuture,异步编程,多用于网络请求等
// 创建高并发计数器
LongAdder adder = new LongAdder();
// 并行执行两个任务, 每个任务执行1000次自增操作
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
IntStream.range(0, 1000).forEach(i -> adder.increment());
});
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
IntStream.range(0, 1000).forEach(i -> adder.increment());
});
// 等待两个任务执行完成
CompletableFuture.allOf(future1, future2).join();
// 输出结果 2000
System.out.println(adder);
// 例子2 使用并行流,批量并行计算,多用于数值计算等
// 创建高并发累加器
LongAccumulator accumulator = new LongAccumulator(
Long::sum,
0L
);
// 并行执行两个任务, 每个任务执行1000次自增操作
IntStream.range(0, 1000).parallel().forEach(i -> accumulator.accumulate(1));
IntStream.range(0, 1000).parallel().forEach(i -> accumulator.accumulate(1));
// 输出结果 2000
System.out.println(accumulator.get());
}
}

浙公网安备 33010602011771号