Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock。

synchronized

1.同步一个代码块
public void func() {synchronized (this) {// ...}
}

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

对于以下代码,使用 ExecutorService 执行了两个线程,由于调用的是同一个对象的同步代码块,因此这两个线程会进行同步,当一个线程进入同步语句块时,另一个线程就必须等待。

public class SynchronizedExample {public void func1() {synchronized (this) {for (int i = 0; i < 10; i++) {System.out.print(i + " ");}}}
}
public static void main(String[] args) {SynchronizedExample e1 = new SynchronizedExample();ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(() -> e1.func1());executorService.execute(() -> e1.func1());
}

输出

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

对于以下代码,两个线程调用了不同对象的同步代码块,因此这两个线程就不需要同步。从输出结果可以看出,两个线程交叉执行。

public static void main(String[] args) {SynchronizedExample e1 = new SynchronizedExample();SynchronizedExample e2 = new SynchronizedExample();ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(() -> e1.func1());executorService.execute(() -> e2.func1());
}

输出

0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
2.同步一个方法
public synchronized void func () {// ...
}

它和同步代码块一样,作用于同一个对象。

3. 同步一个类
public void func() {synchronized (SynchronizedExample.class) {// ...}
}

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

public class SynchronizedExample {public void func2() {synchronized (SynchronizedExample.class) {for (int i = 0; i < 10; i++) {System.out.print(i + " ");}}}
}
public static void main(String[] args) {SynchronizedExample e1 = new SynchronizedExample();SynchronizedExample e2 = new SynchronizedExample();ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(() -> e1.func2());executorService.execute(() -> e2.func2());
}

输出

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
4.同步一个静态方法
public synchronized static void fun() {// ...
}

作用于整个类。

ReentrantLock

ReentrantLock 是 java.util.concurrent(J.U.C)包中的锁。

public class LockExample {private Lock lock = new ReentrantLock();public void func() {lock.lock();try {for (int i = 0; i < 10; i++) {System.out.print(i + " ");}} finally {lock.unlock(); // 确保释放锁,从而避免发生死锁。}}
}
public static void main(String[] args) {LockExample lockExample = new LockExample();ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(() -> lockExample.func());executorService.execute(() -> lockExample.func());
}

输出

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

两者比较

1.锁的实现

synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。

2.性能

新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。

3.等待可中断

当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。

ReentrantLock 可中断,而 synchronized 不行。

4.公平锁

公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。

synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。

5.锁绑定多个条件

一个 ReentrantLock 可以同时绑定多个 Condition 对象。

使用选择

除非需要使用 ReentrantLock 的高级功能,否则优先使用 synchronized。这是因为 synchronized 是 JVM 实现的一种锁机制,JVM 原生地支持它,而 ReentrantLock 不是所有的 JDK 版本都支持。并且使用 synchronized 不用担心没有释放锁而导致死锁问题,因为 JVM 会确保锁的释放。

Java的互斥同步机制相关推荐

  1. java实验多线程机制_使用Java多线程的同步机制编写应用程序 PDF 下载

    使用Java多线程的同步机制编写应用程序 PDF 下载 本站整理下载: 相关截图: 主要内容: 一. 实验名称 使用Java多线程的同步机制编写应用程序 二. 实验目的及要求 1.理解并行/并发的概念 ...

  2. 简要描述临界资源、临界区及互斥同步机制的原则

    简要描述临界资源.临界区及互斥同步机制的原则 答: ①临界资源:指每次只允许一个进程访问的资源,分为硬件.软件临界资源. ②临界区:每个进程中访问临界资源的那段程序,进程对临界区的访问必然相反,每次仅 ...

  3. Java多线程的同步机制(synchronized)

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...

  4. Java高级-线程同步机制实现

    2019独角兽企业重金招聘Python工程师标准>>> 前言 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Threa ...

  5. Java多线程的同步机制:synchronized

    如果程序是单线程的,就不必担心此线程在执行时被其他线程"打扰",就像在现实世界中,在一段时间内如果只能完成一件事情,不用担心做这件事情被其他事情打扰.但是,如果程序中同时使用多线程 ...

  6. java thirteen线程同步机制

    2019独角兽企业重金招聘Python工程师标准>>> 解决资源共享问题的方法一般是在指定时间段内只允许一个线程访问共享资源,这时就需要给共享资源上一道锁,比如售票员售票,当一个售票 ...

  7. JAVA多线程互斥同步例子

    package com.imooc.concurrent.racecondition;/*** 宇宙的能量系统* 遵循能量守恒定律:* 能量不会凭空创生或消失,只会从一处转移到另一处*/ public ...

  8. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除

    文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...

  9. Java线程同步机制synchronized关键字的理解

    由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问. 需要明确的几个问题: ...

最新文章

  1. 二分查找算法的一点改进
  2. 你还在new对象吗?Java8通用Builder了解一下?
  3. probuffer java_Protocol Buffer的使用
  4. Session、Dialog和Transaction的区别
  5. 亮相云栖:这些被Gartner点名的2020年安全风向
  6. appium工作原理详讲
  7. SD卡fat32文件格式说明
  8. 卷积神经网络通俗易懂理解
  9. 大数据平台的开发与思考一:
  10. BZOJ.4598.[SDOI2016]模式字符串(点分治 Hash)
  11. 二叉树的前序遍历(Java)
  12. 超融合和服务器关系_超融合服务器是什么?和超融合一体机有什么区别?
  13. 热乎的面经——踏石留印
  14. 简约二次元网址导航发布页HTML源码
  15. hp固态硬盘安装系统,找不到驱动器和iaStorAfs.sys问题处理
  16. 如何将Excel表中一列数据的分子和分母分别存储
  17. JEOS开源OA系统
  18. PlantUML 入门
  19. python 职业技能大赛备赛(2)
  20. 考研英语作文—遣词造句

热门文章

  1. hdu 4775 Infinite Go(暴力)
  2. [转]Spring中的ContextLoaderListener使用
  3. 年前辞职-WCF入门学习(5)
  4. Linux中JBOSS 安装
  5. 【重识 HTML + CSS】知识点目录
  6. 【MyBatis笔记】03-映射文件的sql语句中 #{} 和 ${} 的区别以及实现模糊查询
  7. Linux不讲武德——开机无法进入登录界面 卡在进度条就不动了
  8. VNPY2.0火币期货交易接口配置使用
  9. 走进我的交易室01_引子
  10. 编译c语言源程序得到的目标文件可以直接在dos环境中运行,c语言练习题一.doc