Java线程锁全面解析:从synchronized到StampedLock,一篇搞定所有锁机制


在多线程编程中,锁是保证线程安全的核心机制。本文将从基础到高级,全面解析Java中的各种锁机制。

引言: 为什么需要锁?

在多线程环境中,多个线程可能同时方位你共享资源,如果不加以控制,就会导致数据不一致,脏读等问题。锁机制正是为了解决这些问题而存在的,它通过互斥访问来保证临界区代码的线程安全。

一、基础锁机制:synchronized

synchronized是Java中最基础、最常用的锁机制,由JVM底层实现。

1.1 三种使用方式

// 1. 同步实例方法- 锁对象是当前实例
public synchronized void instanceMethod(){
   
   
	//临时区代码
}

//2. 同步静态方法 - 锁对象是当前类的Class对象
public static synchronized void staticMethod(){
   
   
	//临时区代码
}
// 3. 同步代码块 - 手动指定锁对象
public void method() {
   
   
    Object lock = new Object();
    synchronized(lock) {
   
   
        // 临界区代码
    }
}

1.2 synchronized的特性

特性 说明
可重入性 同一线程可重复获取同意把锁
非公平锁 不保证线程获取锁的顺序
自动释放 代码块结束或异常时自动释放锁
内存语义 保证可见性和有序性(遵循happens-before原则)

1.3 synchronized的局限性

  1. 无法中断: 等待锁的线程不能中断
  2. 无法超时: 不能设置获取锁的超时时间
  3. 单一条件: 只有一个等待队列(notify随机唤醒)

二、ReenttrantLock: 功能更强大的锁

ReentrantLock是java.util.concurrent.locks包下的显示锁,需要手动获取和释放。

2.1 基本用法

import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo{
   
   
	private final ReentrantLock lock = new ReentrantLock();
	public void doSometing(){
   
   
		lock.lock(); //获取锁
		try{
   
   
		 //临界区代码
		} finally{
   
   
			lock.unlock();//必须在finally中释放。
		}
	}
}

2.2 ReentrantLock的核心优势

1)可中断获取锁

public void tryLockInterruptibly() thows InterruptedException{
   
   
	try{
   
   
		lock.lockInterruptibly();// 可被中断的获取锁方式
		//临界区代码
	} finally{
   
   
		if(lock.isHeldByCurrentThread()){
   
   
			lock.unlock();
		}
	}
}

2) 尝试获取锁(支持超时)

public boolean tryDoSomething(long timeout, TimeUnit unit){
   
   
	try{
   
   
		if(lock.tryLock(timeout,unit)){
   
    //尝试获取锁,支持超时
			try{
   
   
				//临界区代码
				return true;
			} finally{
   
   
				lock.unlock();
			}
		}
		return false;
	} catch (InterruptedException e){
   
   
		Thread.currentThread().interrupt();
	}
}

3) 公平锁与非公平锁

// 公平锁 - 按照请求顺序获取锁
ReentrantLock fairLock = new ReentrantLock(true);

// 非公平锁 - 默认方式,性能更高
ReentrantLock unfairLock = new ReentrantLock(false);

4) 多条件变量

class BoundedBuffer {
   
   
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();   // 条件:不满
    private final Condition notEmpty = lock.newCondition()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值