“可重入锁”的概念是:自己可以再次获得自己的内部锁。比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁。

  1. class sysTest{
  2. synchronized void test1(String str){
  3. System.out.println(str+"1");
  4. test2(str);
  5. System.out.println("end" + str);
  6. }
  7.  
  8. synchronized void test2(String str){
  9. System.out.println(str+"2");
  10. }
  11. }
  12.  
  13. class myThread extends Thread{
  14. String str = null;
  15. public myThread(String str) {
  16. this.str = str;
  17. }
  18. @Override
  19. public void run() {
  20. // TODO Auto-generated method stub
  21. super.run();
  22. new sysTest().test1(str);
  23. }
  24. }
  25.  
  26. public class synchronizedTest {
  27.  
  28. public static void main(String[] args) {
  29. // TODO Auto-generated method stub
  30. myThread th1 = new myThread("1str");
  31. myThread th2 = new myThread("2str");
  32. th1.start();
  33. th2.start();
  34. }
  35.  
  36. }

在加粗的sychronized在的时候结果会有下面,结果不唯一的:

1str1

2str1

1str2

2str2

end2str

end1str

在加粗的sychronized去掉的时候结果会有下面,结果唯一的:

1str1

1str2

end1str

2str1

2str2

end2str

在这里必须要认识到,加一个sychronized方法里调用sychronized方法会造成不同步,需要注意。原因是两个锁的问题,

这个时候使用可重入概念解决的话,就要使用对象锁,因为在sychronized()代码块中再次获得该锁就会可以得到:

  1. class sysTest{
  2. static Object object = new Object();
  3. void test1(String str){
  4. synchronized(object){
  5. System.out.println(str+"1");
  6. test2(str);
  7. System.out.println("end" + str);
  8. }
  9.  
  10. }
  11.  
  12. void test2(String str){
  13. synchronized(object){
  14. System.out.println(str+"2");
  15. }
  16. }
  17. }
  18.  
  19. class myThread extends Thread{
  20. String str = null;
  21. public myThread(String str) {
  22. this.str = str;
  23. }
  24. @Override
  25. public void run() {
  26. // TODO Auto-generated method stub
  27. super.run();
  28. new sysTest().test1(str);
  29. }
  30. }
  31.  
  32. public class synchronizedTest {
  33.  
  34. public static void main(String[] args) {
  35. // TODO Auto-generated method stub
  36. myThread th1 = new myThread("1str");
  37. myThread th2 = new myThread("2str");
  38. th1.start();
  39. th2.start();
  40. }
  41.  
  42. }
  43. 结果:
  44. 1str1
  45. 1str2
  46. end1str
  47. 2str1
  48. 2str2
  49. end2str

Java多线程可重入锁例子解析的更多相关文章

  1. Java多线程——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...

  2. AQS学习(二) AQS互斥模式与ReenterLock可重入锁原理解析

    1. MyAQS介绍    在这个系列博客中,我们会参考着jdk的AbstractQueuedLongSynchronizer,从零开始自己动手实现一个AQS(MyAQS).通过模仿,自己造轮子来学习 ...

  3. 探索JAVA并发 - 可重入锁和不可重入锁

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  4. Java中可重入锁ReentrantLock原理剖析

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一. 概述 本文首先介绍Lock接口.ReentrantLock的类层次结构以及锁功能模板类AbstractQue ...

  5. 可重入锁ReentrantLock解析

    说到可重入锁,先从AQS的ConditionObject说起,AQS的内部类ConditionObject是构建显示锁条件队列的基础.之前AQS的解析没有说这个内部类,这里和ReentrantLock ...

  6. java ReentrantLock可重入锁功能

    1.可重入锁是可以中断的,如果发生了死锁,可以中断程序 //如下程序出现死锁,不去kill jvm无法解决死锁 public class Uninterruptible { public static ...

  7. Java并发:重入锁 ReentrantLock(一)

    ReentrantLock 是一种可重入的互斥锁,它不像 synchronized关键字一样支持隐式的重进入,但能够使一个线程(不同的方法)重复对资源的重复加锁而不受阻塞. ReentrantLock ...

  8. java ReentrantLock可重入锁的使用场景

    摘要 从使用场景的角度出发来介绍对ReentrantLock的使用,相对来说容易理解一些. 场景1:如果发现该操作已经在执行中则不再执行(有状态执行) a.用在定时任务时,如果任务执行时间可能超过下次 ...

  9. Java并发:重入锁 ReentrantLock(二)

    一.理解锁的实现原理 1. 用wait()去实现一个lock方法,wait()要和synchronized同步关键字一起去使用的,直接使用wait方法会直接报IllegalMonitorStateEx ...

随机推荐

  1. Java实现 LeetCode 46 全排列

    46. 全排列 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2] ...

  2. java实现排列序数

    X星系的某次考古活动发现了史前智能痕迹. 这是一些用来计数的符号,经过分析它的计数规律如下: (为了表示方便,我们把这些奇怪的符号用a~q代替) abcdefghijklmnopq 表示0 abcde ...

  3. Java实现Labeling Balls(拓扑排序的应用)

    1 问题描述 给出一些球,从1N编号,他们的重量都不相同,也用1N标记加以区分(这里真心恶毒啊,估计很多WA都是因为这里),然后给出一些约束条件,< a , b >要求编号为 a 的球必须 ...

  4. hibernate 用注解方式生成uuid方法

    //配置uuid,本来jpa是不支持uuid的,但借用hibernate的方法可以实现. @GeneratedValue(generator = "uuid") @Generate ...

  5. jsp页面用DBHelper实现简单的登陆验证

    首先我们需要写一个简单的登陆页面login.jsp,然后用from表单提交给index.jsp页面.在index.jsp页面通过DBHelper连接数据库判断账号和密码,如果密码正确则显示登陆成功. ...

  6. Base-64字符串无效,The input is not a valid Base-64 string as it contains a non-base 64 character

    base64规则: * 字符串只可能包含A-Z,a-z,0-9,+,/,=字符* 字符串长度是4的倍数* =只会出现在字符串最后,可能没有或者一个等号或者两个等号 首先,C# 做上传文件的时候,需要替 ...

  7. 如何在微信小程序中使用骨架屏

    先上效果图

  8. hadoop知识整理(4)之zookeeper

    一.介绍 一个分布式协调服务框架: 一个精简的文件系统,每个节点大小最好不大于1MB: 众多hadoop组件依赖于此,比如hdfs,kafka,hbase,storm等: 旨在,分布式应用中,提供一个 ...

  9. 没有国产主机,怎么开发:交叉编译和QEMU虚拟机

    1. 背景 近期国产化的趋势越来越浓,包括国产操作系统.国产CPU等.时隔十多年,QQ for Linux也更新了.做为软件开发人员,"有幸"也需要适配国产化.至于国产化的意义等就 ...

  10. @codeforces - 668E@ Little Artem and 2-SAT

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定两个 2-sat 问题,询问两个问题的解集是否相同. 如果不 ...