Java技术债务Java技术债务

  •  首页
  •  分类
  •  归档
  •  标签
  • 博客日志
  • 资源分享
  •  友链
  •  关于本站
注册
登录

JUC容器介绍

Java,多线程,JUC

文章目录

  • JUC结构
  • 1、tools(工具类)
  • 2、executor
  • 3、atomic
  • 4、Lock锁(重点)
  • 5、集合类不安全

JUC结构

JUC容器介绍 - Java技术债务

  1. tools(工具类):又叫信号量三组工具类,包含有

    1. CountDownLatch(倒计数) 是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
    2. CyclicBarrier(循环栅栏) 之所以叫barrier,是因为是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 ,并且在释放等待线程后可以重用。
    3. Semaphore(信号量) 是一个计数信号量,它的本质是一个“共享锁“。信号量维护了一个信号量许可集。线程可以通过调用 acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。
  2. executor(执行者):是Java里面线程池的顶级接口,但它只是一个执行线程的工具,真正的线程池接口是ExecutorService,里面包含的类有:

    1. ScheduledExecutorService 解决那些需要任务重复执行的问题
    2. ScheduledThreadPoolExecutor 周期性任务调度的类实现
  3. atomic(原子性包):是JDK提供的一组原子操作类,

  4. locks(锁包):是JDK提供的锁机制,相比synchronized关键字来进行同步锁,功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁包含的实现类有:

    1. ReentrantLock 它是独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。
    2. ReentrantReadWriteLock 它包括子类ReadLock和WriteLock。ReadLock是共享锁,而WriteLock是独占锁。
    3. LockSupport 它具备阻塞线程和解除阻塞线程的功能,并且不会引发死锁。
  5. collections(集合类):主要是提供线程安全的集合, 比如:

    1. ArrayList对应的高并发类是CopyOnWriteArrayList,
    2. HashSet对应的高并发类是 CopyOnWriteArraySet,
    3. HashMap对应的高并发类是ConcurrentHashMap等等

1、tools(工具类)

JUC 中的同步器三个主要的成员:CountDownLatch、CyclicBarrier 和 Semaphore,通过它们可以方便地实现很多线程之间协作的功能。

CountDownLatch

**叫倒计数,**允许一个或多个线程等待某些操作完成。

看几个场景:1、跑步比赛,裁判需要等到所有的运动员(“其他线程”)都跑到终点(达到目标),才能去算排名和颁奖。

2、模拟并发,我需要启动 100 个线程去同时访问某一个地址,我希望它们能同时并发,而不是一个一个的去执行。

**用法:**CountDownLatch 构造方法指明计数数量,被等待线程调用 countDown 将计数器减 1,等待线程使用 await 进行线程等待。 JUC容器介绍 - Java技术债务

CyclicBarrier

叫循环栅栏,它实现让一组线程等待至某个状态之后再全部同时执行,而且当所有等待线程被释放后,CyclicBarrier 可以被重复使用。CyclicBarrier 的典型应用场景是用来等待并发线程结束。

CyclicBarrier 的主要方法是 await(),await() 每被调用一次,计数便会减少 1,并阻塞住当前线程。当计数减至 0 时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。在这之后,如果再次调用 await(),计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。CyclicBarrier.await() 带有返回值,用来表示当前线程是第几个到达这个 Barrier 的线程。 JUC容器介绍 - Java技术债务

Semaphore

Java 版本的信号量实现,用于控制同时访问的线程个数,来达到限制通用资源访问的目的,其原理是通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

如果 Semaphore 的数值被初始化为 1,那么一个线程就可以通过 acquire 进入互斥状态,本质上和互斥锁是非常相似的。

但是区别也非常明显,比如互斥锁是有持有者的,而对于 Semaphore 这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。 JUC容器介绍 - Java技术债务

CyclicBarrier 和 CountDownLatch 区别

CountDownLatch 是不可以重置的,所以无法重用,CyclicBarrier 没有这种限制,可以重用。

CountDownLatch 的基本操作组合是 countDown/await,调用 await 的线程阻塞等待 countDown 足够的次数,不管你是在一个线程还是多个线程里 countDown,只要次数足够即可。CyclicBarrier 的基本操作组合就是 await,当所有的伙伴都调用了 await,才会继续进行任务,并自动进行重置。

CountDownLatch 目的是让一个线程等待其他 N 个线程达到某个条件后,自己再去做某个事(通过 CyclicBarrier 的第二个构造方法 public CyclicBarrier(int parties, Runnable barrierAction),在新线程里做事可以达到同样的效果)。

而 CyclicBarrier 的目的是让 N 多线程互相等待直到所有的都达到某个状态,然后这 N 个线程再继续执行各自后续(通过 CountDownLatch 在某些场合也能完成类似的效果)。

2、executor

关于线程池更多更详细的请看之前的文章:

Java创建线程池的方式

线程池的理解以及使用

3、atomic

包含有AtomicBoolean、AtomicInteger、AtomicIntegerArray等原子变量类,他们的实现原理大多是持有它们各自的对应的类型变量value,而且被volatile关键字修饰了。这样来保证每次一个线程要使用它都会拿到最新的值。

4、Lock锁(重点)

什么是Synchronized?

Synchronized和lock

  1. Lock是一个接口,而synchronized是关键字。
  2. synchronized会自动释放锁,而Lock必须手动释放锁。
  3. Lock可以让等待锁的线程响应中断,而synchronized不会,线程会一直等待下去。
  4. 通过Lock可以知道线程有没有拿到锁,而synchronized不能。
  5. Lock能提高多个线程读操作的效率。
  6. synchronized能锁住类、方法和代码块,而Lock是块范围内的

synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。JDK1.5以后引入了自旋锁、锁粗化、轻量级锁,偏向锁来有优化关键字的性能。

Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

Syncronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?

JUC容器介绍 - Java技术债务

synchronized修饰静态方法以及同步代码块的synchronized (类.class)用法锁的是类,线程想要执行对应同步代码,需要获得类锁。

synchronized修饰成员方法,线程获取的是当前调用该方法的对象实例的对象锁。

对象锁: 它只作用于同一个对象,如果调用两个同一个类的对象上的同步代码块,就不会进行同步。

类锁: 锁住的是当前类的 Class 对象,它会作用于整个类,也就是说两个线程调用同一个类的不同对象上的这种同步语句,也会进行同步。

1、有线程访问对象的同步代码块时,其他线程是可以访问该对象的非同步代码块的。

2、若锁住的是同一个对象,一个线程在访问对象的同步代码块(同步方法)时,另一个访问对象的同步代码块(同步方法)的线程会被阻塞。

3、若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象同步方法的线程会被阻塞,反之亦然(这点在后续介绍 synchronized 底层原理之后你就会明白原因了)。

4、同一个类的不同对象的对象锁互不干扰

5、类锁作用于整个类

更多锁(ReentrantLock、ReadWriteLock读写锁)的文章请关注更多文章

5、集合类不安全

ArrayList、HashSet、HashMap线程都不安全

在集合中 Vector 和 HashTable 是线程安全的。源码中把各自核心方法添加上了synchronized 关键字。

Collections 工具类提供了相关的 API,可以让上面那 3 个不安全的集合变为安全的。

  1. Collections.synchronizedCollection(c)

  2. Collections.synchronizedList(list)

  3. Collections.synchronizedMap(m)

  4. Collections.synchronizedSet(s)

JUC结构

JUC容器介绍 - Java技术债务

  1. tools(工具类):又叫信号量三组工具类,包含有

    1. CountDownLatch(倒计数) 是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
    2. CyclicBarrier(循环栅栏) 之所以叫barrier,是因为是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 ,并且在释放等待线程后可以重用。
    3. Semaphore(信号量) 是一个计数信号量,它的本质是一个“共享锁“。信号量维护了一个信号量许可集。线程可以通过调用 acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。
  2. executor(执行者):是Java里面线程池的顶级接口,但它只是一个执行线程的工具,真正的线程池接口是ExecutorService,里面包含的类有:

    1. ScheduledExecutorService 解决那些需要任务重复执行的问题
    2. ScheduledThreadPoolExecutor 周期性任务调度的类实现
  3. atomic(原子性包):是JDK提供的一组原子操作类,

  4. locks(锁包):是JDK提供的锁机制,相比synchronized关键字来进行同步锁,功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁包含的实现类有:

    1. ReentrantLock 它是独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。
    2. ReentrantReadWriteLock 它包括子类ReadLock和WriteLock。ReadLock是共享锁,而WriteLock是独占锁。
    3. LockSupport 它具备阻塞线程和解除阻塞线程的功能,并且不会引发死锁。
  5. collections(集合类):主要是提供线程安全的集合, 比如:

    1. ArrayList对应的高并发类是CopyOnWriteArrayList,
    2. HashSet对应的高并发类是 CopyOnWriteArraySet,
    3. HashMap对应的高并发类是ConcurrentHashMap等等

1、tools(工具类)

JUC 中的同步器三个主要的成员:CountDownLatch、CyclicBarrier 和 Semaphore,通过它们可以方便地实现很多线程之间协作的功能。

CountDownLatch

**叫倒计数,**允许一个或多个线程等待某些操作完成。

看几个场景:1、跑步比赛,裁判需要等到所有的运动员(“其他线程”)都跑到终点(达到目标),才能去算排名和颁奖。

2、模拟并发,我需要启动 100 个线程去同时访问某一个地址,我希望它们能同时并发,而不是一个一个的去执行。

**用法:**CountDownLatch 构造方法指明计数数量,被等待线程调用 countDown 将计数器减 1,等待线程使用 await 进行线程等待。 JUC容器介绍 - Java技术债务

CyclicBarrier

叫循环栅栏,它实现让一组线程等待至某个状态之后再全部同时执行,而且当所有等待线程被释放后,CyclicBarrier 可以被重复使用。CyclicBarrier 的典型应用场景是用来等待并发线程结束。

CyclicBarrier 的主要方法是 await(),await() 每被调用一次,计数便会减少 1,并阻塞住当前线程。当计数减至 0 时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。在这之后,如果再次调用 await(),计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。CyclicBarrier.await() 带有返回值,用来表示当前线程是第几个到达这个 Barrier 的线程。 JUC容器介绍 - Java技术债务

Semaphore

Java 版本的信号量实现,用于控制同时访问的线程个数,来达到限制通用资源访问的目的,其原理是通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

如果 Semaphore 的数值被初始化为 1,那么一个线程就可以通过 acquire 进入互斥状态,本质上和互斥锁是非常相似的。

但是区别也非常明显,比如互斥锁是有持有者的,而对于 Semaphore 这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。 JUC容器介绍 - Java技术债务

CyclicBarrier 和 CountDownLatch 区别

CountDownLatch 是不可以重置的,所以无法重用,CyclicBarrier 没有这种限制,可以重用。

CountDownLatch 的基本操作组合是 countDown/await,调用 await 的线程阻塞等待 countDown 足够的次数,不管你是在一个线程还是多个线程里 countDown,只要次数足够即可。CyclicBarrier 的基本操作组合就是 await,当所有的伙伴都调用了 await,才会继续进行任务,并自动进行重置。

CountDownLatch 目的是让一个线程等待其他 N 个线程达到某个条件后,自己再去做某个事(通过 CyclicBarrier 的第二个构造方法 public CyclicBarrier(int parties, Runnable barrierAction),在新线程里做事可以达到同样的效果)。

而 CyclicBarrier 的目的是让 N 多线程互相等待直到所有的都达到某个状态,然后这 N 个线程再继续执行各自后续(通过 CountDownLatch 在某些场合也能完成类似的效果)。

2、executor

关于线程池更多更详细的请看之前的文章:

Java创建线程池的方式

线程池的理解以及使用

3、atomic

包含有AtomicBoolean、AtomicInteger、AtomicIntegerArray等原子变量类,他们的实现原理大多是持有它们各自的对应的类型变量value,而且被volatile关键字修饰了。这样来保证每次一个线程要使用它都会拿到最新的值。

4、Lock锁(重点)

什么是Synchronized?

Synchronized和lock

  1. Lock是一个接口,而synchronized是关键字。
  2. synchronized会自动释放锁,而Lock必须手动释放锁。
  3. Lock可以让等待锁的线程响应中断,而synchronized不会,线程会一直等待下去。
  4. 通过Lock可以知道线程有没有拿到锁,而synchronized不能。
  5. Lock能提高多个线程读操作的效率。
  6. synchronized能锁住类、方法和代码块,而Lock是块范围内的

synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。JDK1.5以后引入了自旋锁、锁粗化、轻量级锁,偏向锁来有优化关键字的性能。

Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

Syncronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?

JUC容器介绍 - Java技术债务

synchronized修饰静态方法以及同步代码块的synchronized (类.class)用法锁的是类,线程想要执行对应同步代码,需要获得类锁。

synchronized修饰成员方法,线程获取的是当前调用该方法的对象实例的对象锁。

对象锁: 它只作用于同一个对象,如果调用两个同一个类的对象上的同步代码块,就不会进行同步。

类锁: 锁住的是当前类的 Class 对象,它会作用于整个类,也就是说两个线程调用同一个类的不同对象上的这种同步语句,也会进行同步。

1、有线程访问对象的同步代码块时,其他线程是可以访问该对象的非同步代码块的。

2、若锁住的是同一个对象,一个线程在访问对象的同步代码块(同步方法)时,另一个访问对象的同步代码块(同步方法)的线程会被阻塞。

3、若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象同步方法的线程会被阻塞,反之亦然(这点在后续介绍 synchronized 底层原理之后你就会明白原因了)。

4、同一个类的不同对象的对象锁互不干扰

5、类锁作用于整个类

更多锁(ReentrantLock、ReadWriteLock读写锁)的文章请关注更多文章

5、集合类不安全

ArrayList、HashSet、HashMap线程都不安全

在集合中 Vector 和 HashTable 是线程安全的。源码中把各自核心方法添加上了synchronized 关键字。

Collections 工具类提供了相关的 API,可以让上面那 3 个不安全的集合变为安全的。

  1. Collections.synchronizedCollection(c)

  2. Collections.synchronizedList(list)

  3. Collections.synchronizedMap(m)

  4. Collections.synchronizedSet(s)

完
  • 本文作者:Java技术债务
  • 原文链接: https://cuizb.top/myblog/article/1646880441
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY 3.0 CN协议进行许可。转载请署名作者且注明文章出处。
阅读全文
Java技术债务

Java技术债务

Java技术债务
Java技术债务
热门文章
  1. ClickHouse使用过程中的一些查询优化(六)2003
  2. MySQL数据库被攻击,被删库勒索,逼迫我使出洪荒之力进行恢复数据764
  3. MySQL主从同步原理458
  4. 线程池的理解以及使用414
  5. Spring Cloud Gateway整合nacos实战(三)409
分类
  • Java
    30篇
  • 设计模式
    27篇
  • 数据库
    20篇
  • Spring
    18篇
  • MySQL
    13篇
  • ClickHouse
    11篇
  • Kubernetes
    10篇
  • Redis
    9篇
  • Docker
    8篇
  • SpringBoot
    7篇
  • JVM
    6篇
  • Linux
    5篇
  • Spring Cloud
    5篇
  • 多线程
    5篇
  • Netty
    4篇
  • Kafka
    4篇
  • 面经
    4篇
  • Nginx
    3篇
  • JUC
    3篇
  • 随笔
    2篇
  • 分布式
    1篇
  • MyBatis
    1篇
  • 报错合集
    1篇
  • 生活记录
    1篇
  • 源码
    1篇
  • 性能优化
    1篇

最新评论

  • MySQL数据库被攻击,被删库勒索,逼迫我使出洪荒之力进行恢复数据2022-05-06
    Java技术债务:@capture 一起探讨学习,服务器被黑很正常,及时做好备份以及做好防护
  • MySQL数据库被攻击,被删库勒索,逼迫我使出洪荒之力进行恢复数据2022-04-13
    capture:我的刚上线两天,网站里就两篇文章也被攻击了,纳闷
  • Java常用集合List、Map、Set介绍以及一些面试问题2022-01-18
    Java技术债务:HashSet和TreeSet 相同点:数据不能重复 不同点: 1、底层存储结构不同; HashSet底层使用HashMap哈希表存储 TreeSet底层使用TreeMap树结构存储 2、唯一性方式不同 HashSet底层使用hashcode()和equal()方法判断 TreeSet底层使用Comparable接口的compareTo判断的 3、HashSet无序,TreeSet有序
  • undefined2021-12-14
    Java技术债务:如果不指定线程池,CompletableFuture会默认使用ForkJoin线程池,如果同一时间出现大量请求的话,会出现线程等待问题,建议使用自定义线程池。。。
  • undefined2021-12-02
    you:很好,对于小白相当不错了,谢谢
  • CSDN
  • 博客园
  • 程序猿DD
  • 纯洁的微笑
  • spring4all
  • 廖雪峰的官方网站
  • 猿天地
  • 泥瓦匠BYSocket
  • crossoverJie
  • 张先森个人博客
  • 越加网

© 2021-2022 Java技术债务 - Java技术债务 版权所有
总访问量 0 次 您是本文第 0 位童鞋
豫ICP备2021034516号
Java技术债务 豫公网安备 51011402000164号

微信公众号

Java技术债务
Java技术债务

专注于Spring,SpringBoot等后端技术探索

以及MySql数据库开发和Netty等后端流行框架学习

日志
分类
标签
RSS

有不足之处也希望各位前辈指出