从头认识多线程-2.5 锁的可重入性

本文介绍了可重入锁的概念及特点,包括同一对象不同方法间如何获取相同的锁,并通过示例代码展示了其工作原理。此外,还探讨了可重入锁在解决自旋锁死锁问题中的应用。

这一章节我们来讨论一下锁的可重入性。

1.什么是可重入锁?

一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获得锁。


2.特性:

(1)同一对象,不同方法,可以获取同样的锁,然后重入

package com.ray.deepintothread.ch02.topic_5;

public class ReGetInTheLock {
	public static void main(String[] args) throws InterruptedException {
		MyTestObjectOne myTestObjectOne = new MyTestObjectOne();
		ThreadOne threadOne = new ThreadOne(myTestObjectOne);
		Thread thread = new Thread(threadOne);
		thread.start();
	}
}

class ThreadOne implements Runnable {

	private MyTestObjectOne myTestObjectOne;

	public ThreadOne(MyTestObjectOne myTestObjectOne) {
		this.myTestObjectOne = myTestObjectOne;
	}

	@Override
	public void run() {
		myTestObjectOne.service_1();
	}
}

class MyTestObjectOne {
	public synchronized void service_1() {
		System.out.println("service_1 begin");
		service_2();
		System.out.println("service_1 end");
	}

	public synchronized void service_2() {
		System.out.println("service_2 begin");
		service_3();
		System.out.println("service_2 end");
	}

	public synchronized void service_3() {
		System.out.println("service_3 begin");
		System.out.println("service_3 end");
	}
}

输出:

service_1 begin
service_2 begin
service_3 begin
service_3 end
service_2 end
service_1 end


(2)继承关系,父子获取同样的锁

package com.ray.deepintothread.ch02.topic_5;

public class ReGetInTheLock2 {
	public static void main(String[] args) throws InterruptedException {
		Sub sub = new Sub();
		ThreadTwo threadTwo = new ThreadTwo(sub);
		Thread thread = new Thread(threadTwo);
		thread.start();
	}
}

class ThreadTwo implements Runnable {

	private Sub sub;

	public ThreadTwo(Sub sub) {
		this.sub = sub;
	}

	@Override
	public void run() {
		sub.show();
	}
}

class Father {
	public void show() {
		System.out.println("father show");
	}
}

class Sub extends Father {
	@Override
	public void show() {
		System.out.println("sub show");
		super.show();
	}
}

输出:

sub show
father show


3.使用场景

解决自旋锁的死锁问题

自旋锁实例:

public class SpinLock {

  private AtomicReference<Thread> sign =new AtomicReference<>();

  public void lock(){
    Thread current = Thread.currentThread();
    while(!sign .compareAndSet(null, current)){
    }
  }

  public void unlock (){
    Thread current = Thread.currentThread();
    sign .compareAndSet(current, null);
  }
}

关于Atomic的几个方法 
getAndSet() : 设置新值,返回旧值. 
compareAndSet(expectedValue, newValue) : 如果当前值(current value)等于期待的值(expectedValue), 则原子地更新指定值为新值(newValue), 如果更新成功,返回true, 否则返回false, 换句话可以这样说: 将原子变量设置为新的值, 但是如果从我上次看到的这个变量之后到现在被其他线程修改了(和我期望看到的值不符), 那么更新失败

(其实笔者还没有使用过原子类的操作,所以解释的不清不楚)

都是引用自:http://blog.youkuaiyun.com/jationxiaozi/article/details/6322151


总结:这一章节展现了可重入锁以及它的特性。


这一章节就到这里,谢谢

------------------------------------------------------------------------------------

我的github:https://github.com/raylee2015/DeepIntoThread


目录:http://blog.youkuaiyun.com/raylee2007/article/details/51204573




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值