Java多线程- synchronized关键字总结

简介: Java多线程- synchronized关键字总结

线程锁的概要

     首先对于锁的条件和要点进行一个总结:

  • 锁使用来保护代码片段的, 以保证多线程的安全性, 一次只允许一个线程执行被保护的代码.
  • 锁可以管理视图进入被保护代码的线程, 提高多线程安全
  • 一个锁可以有一个或多个关联的条件对象

对于synchronized来说, 如果它修饰的是方法, 那么他保护的代码段将是整个方法

Synchronized关键字

       结合锁策略, 可以得出以下结论:

  1. synchronized开始是乐观锁, 如果冲突太频繁了, 那么synchronized就升级为悲观锁
  2. synchronized开始是轻量级锁, 如果单个线程占用synchronized锁的时间长了, 就会变成重量级锁.
  3. 此处的轻量级锁和自旋锁有重叠的部分
  4. synchronized是一种不公平的锁
  5. synchronized是一种可重入锁
  6. synchronized不是读写锁

synchronized加锁过程

  1. 首先对一个无锁的代码段进行加锁,  这个锁会进入偏向锁的状态, 此处的偏向锁不是真正的加锁, 而是给这个锁做一个标记, 表示这个锁属于哪个线程, 如果后续没有线程来抢锁, 那么就不会进行其他同步操作.  如果有的话, 那么这个锁就会升级为真正的锁, 进入一种以自旋锁为基础的轻量级锁状态
  2. 进入轻量级锁, 此处的轻量级锁是通过CAS实现的, 轻量级锁适用于抢锁比较少的多线程环境, 基于自旋锁, 如果其他线程来抢锁就会阻塞等待, 并且在极短时间内进行第二次访问, 直到拿到锁. 但是如果锁长时间没有释放就会造成CPU空转, 浪费CPU资源. 所以如果有多个线程频繁的抢锁, 锁就会升级为重量级锁. 让线程放弃CPU, 进入内核态,此时有操作系统来通知线程这个锁是否被释放, 然后再来调度这些抢锁的线程.
  3. 轻量级锁的竞争激烈后, 就会升级为重量级锁,如果该锁被占用, 则加锁失败. 此时线程进入锁的等待队列, 挂起. 等待被操作系统唤醒.经过一段时间后, 这个锁被其他线程释放了, 操作系统也想起了这个挂起的线程, 于是唤醒这个线程, 尝试重新获取锁.

synchronized锁优化

       锁消除

       遵循于非必要不加锁的规则, synchronized实现了锁消除机制, 也就是在非多线程情况下, synchronized会自动识别线程情况, 自动消除掉不必要的锁,

       例如我们常用的线程安全的StringBuffer, 但是如果在单线程使用, 那么就会在编译的时候去除synchronized关键字, 来减少非必要的开销.

StringBuffer sb = new StringBuffer();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");

此处每次的append操作都会加锁, 造成了非必要的资源浪费

       锁粗化

       在一段代码中, 可能存在两个被保护的代码段, 如下:

如果这两个代码段(代码段1和代码段2)之间, 不存在锁竞争的情况话, 就可以省去中间的解锁和加锁, 这样就避免的多余的加锁解锁操作, 节约了CPU资源


目录
相关文章
|
2天前
|
Java API
详细探究Java多线程的线程状态变化
Java多线程的线程状态主要有六种:新建(NEW)、可运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)和终止(TERMINATED)。线程创建后处于NEW状态,调用start()后进入RUNNABLE状态,表示准备好运行。当线程获得CPU资源,开始执行run()方法时,它处于运行状态。线程可以因等待锁或调用sleep()等方法进入BLOCKED或等待状态。线程完成任务或发生异常后,会进入TERMINATED状态。
|
2天前
|
存储 安全 Java
Java多线程中线程安全问题
Java多线程中的线程安全问题主要涉及多线程环境下对共享资源的访问可能导致的数据损坏或不一致。线程安全的核心在于确保在多线程调度顺序不确定的情况下,代码的执行结果始终正确。常见原因包括线程调度随机性、共享数据修改以及原子性问题。解决线程安全问题通常需要采用同步机制,如使用synchronized关键字或Lock接口,以确保同一时间只有一个线程能够访问特定资源,从而保持数据的一致性和正确性。
|
2天前
|
监控 安全 Java
Java多线程的使用
Java多线程允许程序同时执行多个任务,提高了系统的整体性能和响应速度。通过创建Thread类或其子类的实例,或使用Runnable接口,Java开发者可以定义并发执行的代码段。多线程在处理复杂任务、资源共享、网络通信等方面具有显著优势,但也需要注意线程安全、同步和死锁等问题。Java提供了丰富的API和工具来处理这些并发问题,使多线程编程更加高效和可靠。
|
2天前
|
API
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
6 1
|
2天前
|
安全 Java 程序员
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(二)
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(二)
23 4
|
17天前
|
安全 Java 编译器
Java多线程基础-6:线程安全问题及解决措施,synchronized关键字与volatile关键字(一)
线程安全问题是多线程编程中最典型的一类问题之一。如果多线程环境下代码运行的结果是符合我们预期的,即该结果正是在单线程环境中应该出现的结果,则说这个程序是线程安全的。 通俗来说,线程不安全指的就是某一代码在多线程环境下执行会出现bug,而在单线程环境下执行就不会。线程安全问题本质上是由于线程之间的调度顺序的不确定性,正是这样的不确定性,给我们的代码带来了很多“变数”。 本文将对Java多线程编程中,线程安全问题展开详细的讲解。
36 0
|
安全 Java 数据安全/隐私保护
Java基础进阶多线程-线程安全和synchronized关键字
Java基础进阶多线程-线程安全和synchronized关键字
Java基础进阶多线程-线程安全和synchronized关键字
|
Java 数据安全/隐私保护
Java——多线程高并发系列之synchronized关键字
Java——多线程高并发系列之synchronized关键字
Java——多线程高并发系列之synchronized关键字
|
Java
Java多线程学习(二)synchronized关键字(2)
使用<font color="red">synchronized关键字</font>声明方法有些时候是有很大的弊端的,比如我们有两个线程一个线程A调用同步方法后获得锁,那么另一个线程B就需要等待A执行完,但是如果说A执行的是一个很费时间的任务的话这样就会很耗时。
3577 0