Day32 线程安全二

Day32 线程安全二

一、线程安全 – ArrayList

1、前言:ArrayList是线程不安全的集合

2、解决方案1:使用Vector – synchronized锁

3、解决方案2:使用Collections的synchronizedList方法将ArrayList转换为线程安全的集合 – synchronized锁

ArrayList<Object> list = new ArrayList<>();

List<Object> synchronizedList = Collections.synchronizedList(list);

4、解决方案3:使用CopyOnWriteArrayList – lock锁

CopyOnWriteArrayList<Object> list = new CopyOnWriteArrayList<>();
	list.add("aaa");
	list.add("bbb");
	list.add("ccc");
	list.add("ddd");

5、总结:Vector和synchronizedList()底层使用synchronized(重量级锁),效率很低。项目中推荐使用CopyOnWriteArrayList

二、线程安全 – 死锁

1、概念:

死锁(Deadlock)是指两个或多个线程在互相等待对方释放资源的情况下,导致它们无法继续执行的现象。在死锁情况下,每个线程都在等待另一个线程释放资源,从而导致所有线程都无法继续执行,造成程序无法正常运行。

2、 死锁产生的四个必要条件 :

  1. 互斥条件:至少有一个资源必须处于非共享模式,即一次只能被一个线程使用。
  2. 请求与保持条件:线程至少持有一个资源,并且在等待获取其他资源。
  3. 不剥夺条件:线程已经获得的资源在未使用完之前不能被其他线程抢占。
  4. 循环等待条件:存在一个循环等待序列,每个线程都在等待下一个线程所持有的资源。

3、 避免死锁的方法 :

  1. 避免使用多个锁:尽量减少同一时刻持有多个锁的情况,可以考虑使用更高级别的锁机制,如并发集合类。
  2. 按顺序获取锁:确保线程获取锁的顺序是一致的,避免循环等待的情况。
  3. 设置超时时间:在获取锁时设置超时时间,避免线程无限等待。
  4. 死锁检测和恢复:定期检测死锁的发生,并采取相应的恢复措施。

注意:多个线程中的多个锁对象被互相占用

解决方案:尽可能的不要使用锁嵌套

三、线程安全 – 可重入锁

1、概念:

可重入锁(Reentrant Lock)是一种支持重复加锁的锁机制,允许同一个线程多次获取同一把锁,而不会导致死锁。可重入锁在多线程编程中非常有用,可以避免死锁情况,并提供更多灵活性和控制选项。

2、 可重入锁的特点 :

  1. 重入性:同一个线程可以多次获取同一把锁,而不会被阻塞,确保了线程安全性。
  2. 公平性:可重入锁可以设置为公平锁或非公平锁,公平锁会按照线程请求的顺序获取锁。
  3. 可中断性:可重入锁支持可中断的获取锁操作,当线程在等待锁时可以响应中断。
  4. 超时性:可重入锁支持尝试获取锁的操作,并可以设置超时时间,避免线程无限等待。
  5. 条件变量:可重入锁支持条件变量,可以通过条件对象实现线程的等待和通知机制。

3、重要性:

在 Java 中,ReentrantLock 是可重入锁的一个常用实现类,提供了上述特性,并且比传统的 synchronized 关键字更加灵活和功能强大。使用可重入锁可以更精细地控制多线程之间的并发访问,避免死锁和提高程序的性能。

4、示例:

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private ReentrantLock lock = new ReentrantLock();

    public void doSomething() {
        lock.lock();
        try {
            // 临界区代码
        } finally {
            lock.unlock();
        }
    }
}

代码理解: 在上述示例中,通过 ReentrantLock 实现了可重入锁,使用 lock()unlock() 方法来控制临界区代码的访问。

5、理解:

可重入锁理解

就是一个线程不用释放,可以重复的获取一个锁n次,只是在释放的时候,也需要相应的释放n次。

简单来说

A线程在某上下文中获取了某锁,
当A线程想要再次获取该锁时,不会因为锁已经被自己占用,而需要先等到锁的释放。

注意

synchronized同步代码块是可重入锁
synchronized同步方法是可重入锁
Lock锁是可重入锁

相关推荐

  1. Day32 线安全

    2024-04-09 23:54:01       14 阅读
  2. Day31 线安全

    2024-04-09 23:54:01       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-09 23:54:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-09 23:54:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-09 23:54:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-09 23:54:01       20 阅读

热门阅读

  1. Day31 线程安全一

    2024-04-09 23:54:01       13 阅读
  2. 2024.4.7力扣每日一题——王位继承顺序

    2024-04-09 23:54:01       14 阅读
  3. python--异常处理

    2024-04-09 23:54:01       20 阅读
  4. QB/T 4464-2013 家具用蜂窝板检测

    2024-04-09 23:54:01       15 阅读
  5. vue3基础: 组件注册

    2024-04-09 23:54:01       12 阅读
  6. 微信小程序第六次课(模块化和绑定事件)

    2024-04-09 23:54:01       14 阅读
  7. 题目 2915: 接水问题

    2024-04-09 23:54:01       18 阅读
  8. GDB调试概述

    2024-04-09 23:54:01       13 阅读
  9. 题目 2016: 新生的入队仪式

    2024-04-09 23:54:01       13 阅读