Java同步器简述

一、概述

在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。主要原因是,对于多线程实现实现并发,一直以来,多线程都存在2个问题:

  • 线程之间内存共享,需要通过加锁进行控制,但是加锁会导致性能下降,同时复杂的加锁机制也会增加编程编码难度
  • 过多线程造成线程之间的上下文切换,导致效率低下

因此,在并发编程领域中,一直有一个很重要的设计原则:“不要通过内存共享来实现通信,而应该通过通信来实现内存共享。”

简单来说,就是尽可能通过消息通信,而不是内存共享来实现进程或者线程之间的同步。

  • 并发(Concurrent):在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
  • 并行(Parallel):当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行。
  • 信号量(Semaphore):是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用,也是作系统用来解决并发中的互斥和同步问题的一种方法。
  • 信号量机制(Semaphores):用来解决同步/互斥的问题的,它是1965年,荷兰学者Dijkstra提出了一种卓有成效的实现进程互斥与同步的方法。
  • 管程(Monitor):一般是指管理共享变量以及对共享变量的操作过程,让它们支持并发的一种机制。
  • 互斥(Mutual Exclusion):一个公共资源同一时刻只能被一个进程或线程使用,多个进程或线程不能同时使用公共资源。即就是同一时刻只允许一个线程访问共享资源的问题。
  • 同步(Synchronization):两个或两个以上的进程或线程在运行过程中协同步调,按预定的先后次序运行。即就是线程之间如何通信、协作的问题。
  • 对象池(Object Pool):指的是一次性创建出N个对象,之后所有的线程重复利用这N个对象,当然对象在被释放前,也是不允许其他线程使用的,一般指保存实例对象的容器。

二、线程同步机制

2.1 多线程同步器

同步器 简述
volatile
synchronized

2.2 线程阻塞工具类

同步器 简述
LockSupport AQS中控制线程的实现类,是Java并发基础组件中的基础组件。

2.3 线程锁

同步器 简述
AQS 同步器基类
ReentrantLock
Condition 条件锁
ReentrantReadWriteLock 读写锁
StampedLock 邮戳锁

三、线程辅助类

辅助类 简述
Semaphore 信号灯
CountDownLatch 减计数器
CyclicBarrier 加法计数器
Exchanger 交换器
Phaser 阶段

四、总结

Java三种等待唤醒机制:

  1. synchronized搭配Objectwaitnotify
  2. ReentrantLockawaitsignal方法
  3. LockSupportparkunpark

Object类和ReentrantLock.newCondition提供的阻塞唤醒机制十分相似,体现在:

  1. 要求阻塞和唤醒是有序的:它们都只能先阻塞再唤醒。否则会抛IllegalMonitorStateException异常,且被阻塞的线程不能被唤醒。
  2. 依赖加锁或同步代码块:调用Object的等待唤醒方法时要搭配synchronized一起用。即Objectwaitnotify要写在sync同步代码块内;调用ReentrantLock.newConditionawaitsignal方法时要搭配lockunlock一起用。否则也会抛IllegalMonitorStateException异常,且被阻塞的线程不能被唤醒。

LockSupport类与前两者不同:

LockSupport类支持先唤醒后阻塞,不会抛异常(底层是通过permit通行证实现的)。
LockSupport类不依赖加锁代码块,直接LockSupport.parkLockSupport.park调用即可,较方便。

posted @ 2022-12-16 17:39  夏尔_717  阅读(258)  评论(0编辑  收藏  举报