ReentrantLock与synchronized的区别

 synchronized

synchronized同步锁是使用synchronized关键字将一段代码逻辑锁起来,只有获得这把锁的线程才能访问,并且同一时刻只能有一个线程持有这把锁,保证了线程安全(悲观锁)

sychronized是一种可重入锁,能被同一个线程反复获取,在获取时不仅要哦按段是否是第一次获取还要怕判断是第几次获取,每次退出sychronized次数减一,直到次数为0才算完全退出。

 synchronized关键字的用法

1.修饰实例方法:当前对象this充当锁,只有获取this锁的线程才能访问该方法

class Counter1 {
	// 用于计数的公共变量
	public static int count = 0;
	// 递增
	public void add() {
		for (int i = 0; i < 10000; i++) {
			synchronized (this) {
				Counter1.count += 1;
			}
		}
	}
	// 递减
	public synchronized void dec() {
		for (int i = 0; i < 10000; i++) {
			Counter1.count -= 1;
		}
}
	}

2.修饰静态方法:使用当前对象的Class对象充当锁,只有获取Class对象的线程才能访问该方法

public class Demo03 {
	public static void main(String[] args) {
		//创建foo实例对象
		Foo f=new Foo();
		//创建线程
		Thread th=new Thread() {
				@Override
				public void run() {
					f.dosth1();
				}
			};
			th.start();
	}
}
class Foo{
	//静态方法
	public synchronized static void dosth1() {
		//获取当前对象的class对象锁才能执行该方法
	}
}

3.修饰代码块:所用的锁为某个指定的Java对象

class Counter{
	public static int count=0;
	public static final Object lock=new Object();
}
//递增线程
class AddThread extends Thread{
	@Override
	public void run() {
		//加锁
		synchronized (Counter.lock) {
			for(int i=0;i<1000;i++) {
				Counter.count+=1;
			}
		}
			}
}
//递减线程
class DecrThread extends Thread{
	@Override
	public void run() {
		//加锁
		synchronized (Counter.lock) {

			for(int i=0;i<1000;i++) {
				Counter.count-=1;
			}
		}
	}
}

ReentrantLock

ReentrantLock和sychronized一样都是可重入锁,但是他在等待释放锁的过程中会有尝试机制。

if(lock.tryLock(1,TimeUnit.SECONDS)) {
			lock.lock();
			try {
				count+=i;
				//将释放锁放于finallly里是防止由于异常无法正常释放
			}finally {
				//释放锁
				lock.unlock();
			}
	}

ReentrantLock实现了Lock接口,Lock接口中定义了lock()  unlock()等方法。它有三个内部类Sync、FairSync、NoFairSync。它的构造方法默认传入的是NoFairSync.

 public ReentrantLock() {
        sync = new NonfairSync();
    }

NoFairSync:每一次都尝试获取锁,不会采取公平等待的原则,即使有些线程长时间都没有获取锁,也不会将锁让给该线程。

FairSync:当有空闲资源时先会考虑队列中等待时间最长的线程。

 

ReentrantLock与synchronized的区别

  • synchronized 可以给类、方法、代码块加锁;而ReentrantLock 只能给代码块加锁。
  • synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而ReentrantLock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁,所以常在finally代码块释放。
  • 通过ReentrantLock可以知道有没有成功获取锁,而 synchronized 不能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值