Java并发编程:JUC学习笔记与线程安全解决方案

需积分: 9 0 下载量 69 浏览量 更新于2024-08-05 收藏 23KB MD 举报
"这是一份关于Java并发编程(JUC)的学习笔记,主要涵盖了虚假唤醒问题、线程不安全的集合处理以及多线程锁的使用等核心知识点。作者通过示例代码展示了各种问题的解决方案,并介绍了锁的工作原理。" ### 一、虚假唤醒问题 在多线程环境下,`wait()`方法可能导致线程被错误地唤醒,即使其等待的条件尚未满足。这是由于线程调度的不确定性导致的。为避免这种问题,应当使用`while`循环进行条件检查,确保在进入临界区之前条件已满足。例如: ```java synchronized(this) { while (num != 0) { this.wait(); } num++; } ``` ### 二、集合线程不安全 #### HashSet解决方案 使用`CopyOnWriteArraySet`,它在修改时会创建一个新的底层数组,保证了线程安全。 #### HashMap解决方案 可以改用`ConcurrentHashMap`,它是线程安全的哈希映射,提供了高并发性能。 #### ArrayList解决方案 1. 使用`Vector`,它内部使用`synchronized`修饰所有方法,实现线程安全。 2. 使用`Collections.synchronizedList`工具类对`ArrayList`进行包装,使其变为线程安全。 3. 使用`CopyOnWriteArrayList`,在写操作时复制底层数组,读操作则无须同步,适合读多写少的场景。 ### 三、多线程锁的使用 #### synchronized锁的范围 - 普通同步方法:锁定的是当前实例对象。 - 静态同步方法:锁定的是当前类的Class对象。 - 同步方法块:锁定的是括号内指定的对象。 #### 公平锁与不公平锁 `ReentrantLock`支持公平和非公平模式。公平锁按照等待队列的顺序唤醒线程,而非公平锁则可能让等待时间短的线程优先获取锁。 ```java // 公平锁 ReentrantLock lock = new ReentrantLock(true); // 非公平锁(默认) ReentrantLock lock = new ReentrantLock(false); ``` #### 可重入锁 `synchronized`关键字和`ReentrantLock`都是可重入锁,允许一个线程在已获得锁的情况下再次进入同步区域,例如: ```java public synchronized void methodA() { // ... methodB(); } public synchronized void methodB() { // ... } ``` 或使用`ReentrantLock`的示例: ```java Lock lock = new ReentrantLock(); lock.lock(); try { // ... lock.lock(); // ... } finally { lock.unlock(); // 释放两次锁 } ``` 以上内容是JUC学习笔记中的关键点,涵盖了多线程编程中常见的问题和解决方案,对于理解和解决并发问题具有重要参考价值。