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

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

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.csdn.net/jationxiaozi/article/details/6322151

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

这一章节就到这里,谢谢

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

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

目录:http://blog.csdn.net/raylee2007/article/details/51204573

时间: 2024-08-02 22:41:51

从头认识多线程-2.4 锁的可重入性的相关文章

偏向锁跟可重入性有什么区别

1. 并发包中的ReentrantLock是偏向锁河轻量级锁码? 是的. 2. 偏向锁跟可重入性有什么区别,非偏向锁如何实现可重入? 偏向锁和可重入性直接没啥关系.. 当然要是锁不具备可重入性,那就无所谓偏向了. 可重入性是指比如一个线程获得了对象A上的锁,如果它第二次请求A的锁必然可以获得(也就是说不会自己把自己锁住),可重入性是线程必须满足的,不然很多代码就会死锁了 偏向锁是说如果线程请求一个自己已经获得的锁,它不会去再次执行lock和unlock,这样可以提升性能. 如何实现可重入都是一样

06 锁:可重入锁 公平锁 读写锁

1.可重入锁 如果锁具备可重入性,则称作为可重入锁. 像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制: 基于线程的分配,而不是基于方法调用的分配. 举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2, 此时线程不必重新去申请锁,而是可以直接执行方法method2. class MyClass { public synch

可重入锁和不可重入锁

锁的简单应用 用lock来保证原子性(this.count++这段代码称为临界区) 什么是原子性,就是不可分,从头执行到尾,不能被其他线程同时执行. 可通过CAS来实现原子操作 CAS(Compare and Swap): CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较下旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换. CAS主要通过compareAndSwapXXX()方法来实现,而这个方法的实现需要涉及底层的unsafe类 unsa

Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等(转)

Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁 / 非公平锁 可重入锁 / 不可重入锁 独享锁 / 共享锁 互斥锁 / 读写锁 乐观锁 / 悲观锁 分段锁 偏向锁 / 轻量级锁 / 重量级锁 自旋锁 上面是很多锁的名词,这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计,下面总结的内容是对每个锁的名词进行一定的解释. 公平锁 / 非公平锁 公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公

36 线程 队列 守护线程 互斥锁 死锁 可重入锁 信号量

线程 线程是操作系统最小的运算调度单位,被包含在进程中,一个线程就是一个固定的 执行流程 线程和进程的关系 线程不能单独存在 必须存在于进程中, 进程是一个资源单位,其包含了运行程序所需的所有资源 线程才是真正的执行单位 没有线程,进程中的资源无法被利用起来,所以一个进程至少包含一个线程,称之为主线程 当我们启动一个程序时,操作系统就会自己为这个程序创建一个主线程 线程可以由程序后期开启 ,自己开启线程称之为子线程 为什么需要线程 目的只有一个就是提高效率 就像一个车间 如果产量跟不上 就再造一

通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底层实现浅尝辄止,但是在需要时能够知道去查什么. 首先要打消一种想法,就是一个锁只能属于一种分类.其实并不是这样,比如一个锁可以同时是悲观锁.可重入锁.公平锁.可中断锁等等,就像一个人可以是男人.医生.健身爱好者.游戏玩家,这并不矛盾.OK,国际惯例,上干货. 〇.synchronized与Lock

写文章 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底层实现浅尝辄止,但是在需要时能够知道去查什么. 首先要打消一种想法,就是一个锁只能属于一种分类.其实并不是这样,比如一个锁可以同时是悲观锁.可重入锁.公平锁.可中断锁等等,就像一个人可以是男人.医生.健身爱好者.游戏玩家,这并不矛盾.OK,国际惯例,上干货. 〇.synchronized与Lock

python多线程编程(3): 死锁和可重入锁

死锁 在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁.尽管死锁很少发生,但一旦发生就会造成应用的停止响应.下面看一个死锁的例子: 按 Ctrl+C 复制代码 按 Ctrl+C 复制代码 执行结果: Thread-1 got resAThread-1 got resBThread-1 got resBThread-1 got resAThread-2 got resAThread-2 got resBThread-2 got resBThread-2

Java并发程序设计(12)并发锁之可重入锁ReentrantLock

1.1. 可重入锁ReentrantLock ReentrantLock是java并发库中提供的可重入锁.与synchronized同步块相比,有相似也有不同.相似的地方有: (1)都可以实现多线程之间的同步,避免对共享资源的访问冲突. (2)都是可重入的,即一个已经获取锁的线程可以再次获得同一个锁,synchronized也类似. 不同的地方有: (1)ReentrantLock更灵活,获取锁和释放锁可以在同一个方法中,也可以在不同方法中.synchronized通常用在同一个方法体内. (2