文章插图
大家好,我是哪吒 。
上一篇简单聊一聊公平锁和非公平锁,parallel并行流,提到了一个IntStream.rangeClosed并行流问题,很多小伙伴,对这个比较陌生,想用线程池的方式改造一下 。一、IntStream.rangeClosed并行流
@Datapublic class LockTest1 {public static void mAIn(String[] args) {IntStream.rangeClosed(1, 100000).parallel().forEach(i -> new LockTest1().increase());System.out.println(time);}private static int time = 0;private static Object lock = new Object();public void increase() {synchronized (lock) {time++;}}}
二、线程池方式改造不会那些新特性,还是原始的香?。?雌鸫?耄?得心应手 。1、创建线程池这时候,有些小伙伴,又陷入了选择恐惧症 。用哪个线程池比较好呢?
简单回顾一下:
- 单线程池newSingleThreadExecutor() , 只有一个核心线程的线程池,保证任务按FIFO顺序一个个执行;
- 固定线程数线程池newFixedThreadPool(10),固定数量的可复用的线程数 , 来执行任务 。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行;
- 可缓存线程池newCachedThreadPool() , 创建的都是非核心线程,而且最大线程数为Interge的最大值,空闲线程存活时间是1分钟 。如果有大量耗时的任务,则不适该创建方式,它只适用于生命周期短的任务;
- 固定线程数newScheduledThreadPool(10),支持定时和周期性任务newScheduledThreadPool(10),顾名思义,在固定线程数的前提下,添加了定时任务 。
@Datapublic class LockTest2 {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(200);for (int i = 0; i < 100000; i++) {Thread0926 thread = new Thread0926();executorService.execute(thread);}System.out.println(time);}private static int time = 0;private static Object lock = new Object();public void increase() {synchronized (lock) {time++;}}}
2、线程类public class Thread0926 implements Runnable{@Overridepublic void run() {LockTest2 lockTest = new LockTest2();lockTest.increase();}}
3、信心满满,走起来我草,这不对?。?挥Ω檬?00000嘛?又把老子整不会了~文章插图
三、再次解决并发时i++原子性问题上一篇测试过 , 使用synchronized代码块是可以解决i++线程安全问题的,这次怎么不好使了?
上面的代码中,synchronized (lock)锁住了time++ , lock是静态变量,所以属于类级别的锁 。但是新建的线程是一个新的类 , 超出了锁的范围,所以失效 。
那么,在当前类中 , 开启线程,是不是就可以了呢?试一下
public class LockTest4 {private static int time = 0;private static Object lock = new Object();public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 200; i++) {Thread thread = new Thread(() -> {for (int j = 0; j < 500; j++) {synchronized (lock) {time++;}}});thread.start();}Thread.sleep(3000);System.out.println(time);}}
当然,在synchronized代码块中,使用synchronized (LockTest4.class)也是可以的 , 效果是一样的 。文章插图
四、并行流与多线程并行流的本质的是并行,多线程的本质是并发 。
并行指当多核CPU中的一个CPU执行一个线程时,其它CPU能够同时执行另一个线程 , 两个线程之间不会抢占CPU资源,可以同时运行 。
并发指在一段时间内CPU处理多个线程,这些线程会抢占CPU资源 , CPU资源根据时间片周期在多个线程之间来回切换,多个线程在一段时间内同时运行,而在同一时刻不是同时运行的 。
1、并行和并发的区别?
- 并行指多个线程在一段时间的每个时刻都同时运行 , 并发指多个线程在一段时间内同时运行(不是同一时刻,一段时间内交叉执行) 。
- 并行的多个线程不会抢占系统资源 , 并发的多个线程会抢占系统资源 。
- 并行是多CPU的产物,单核CPU中只有并发,没有并行 。
文章插图
推荐阅读
- 程序员必会之最详细的ThreadPoolExecutor 线程池七大参数含义
- 并发编程的艺术-“程”:探索进程、线程、协程、纤程与管程
- 怎么看是不是熟普洱
- 去游泳池游泳要带什么
- 为什么72V的电动摩托车,都是配20Ah以上的电池?主要因为3个原因
- 手机电池保养方法有哪些 手机电池保养方法有哪些呢
- 教你顺利通过面试关的秘诀
- 使用充电宝对手机电池有损害吗 使用充电宝对手机电池有损害吗视频
- 怎么在微信上询问面试是否通过 微信怎么问hr面试结果
- 电瓶车如何保护电瓶 电瓶车如何保护电瓶电池