synchronized锁重入:

  关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到一个对象的锁后,再次请求此对象时是可以再次得到该对象的锁。

下面看一段锁重入的小demo:

public class SyncDubbo1 {
public synchronized void method1() {
System.out.println("method1..");
method2();
} public synchronized void method2() {
System.out.println("method2..");
method3();
} public synchronized void method3() {
System.out.println("method3..");
} public static void main(String[] args) {
final SyncDubbo1 sd = new SyncDubbo1();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
sd.method1();
}
});
t1.start();
}
} 这中方式的调用是没有任何问题的,运行的结果是

method1..
method2..
method3..

这是一个最简单的锁重入的问题,是完全没有任何问题的。

下面看一个稍微复杂点的锁重入的代码:

public class SyncDubbo2 {
static class Main {
public int i = 10; private synchronized void operationSup() {
try {
i--;
System.out.println("Main print i = " + i);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} static class Sub extends Main {
public synchronized void operationSub() {
try {
while (i > 0) {
i--;
System.out.println("Sub print i = " + i);
Thread.sleep(100);
this.operationSub();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Sub sub = new Sub();
sub.operationSub();
}
});
}
} 运行结果是:

Sub print i = 9
Main print i = 8
Sub print i = 7
Main print i = 6
Sub print i = 5
Main print i = 4
Sub print i = 3
Main print i = 2
Sub print i = 1
Main print i = 0

这个结果是没有任何问题的,通过这个例子是想说明,再有父子继承关系的时候,然后都加synchronized修饰时,这样去调用也是线程安全的。这是对于synchronized应用的第二种形式。

下面在看一个synchronized中修饰的方法里面,碰到某些异常时,出现的情况,下面也看一个demo;

public class SyncException {
private int i = 0; public synchronized void operation() {
while (true) {
try {
i++;
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " ,i = " + i);
if (i == 5) {
Integer.parseInt("a");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(" log info i = " + i);
}
}
} public static void main(String[] args) {
final SyncException se = new SyncException();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
se.operation();
}
},"t1");
t1.start();
}
}

这段代码在i=5的时候代码发生异常,这种情况下,synchronized会自动解锁,程序会继续执行,发生异常的情况下,我们一定要对异常情况进行处理,运行的结果是:

t1 ,i = 1
t1 ,i = 2
t1 ,i = 3
t1 ,i = 4
t1 ,i = 5
log info i = 5
java.lang.NumberFormatException: For input string: "a"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at Thread.SyncException.operation(SyncException.java:16)
at Thread.SyncException$1.run(SyncException.java:31)
at java.lang.Thread.run(Thread.java:744)
t1 ,i = 6
t1 ,i = 7
t1 ,i = 8

在实际开发中,对 这种异常有两种方式的处理,第一种就是上面写的这种,catch到异常后,把对应的数据记录到日志,当然有个前提条件,就是每次去执行这个任务之间都是没有关联的;还有一种情况,执行的任务是有关联的,是一个整体,假如采用前面那种情况,在异常发生后的几次情况的执行都是有问题的,这也有一个解决方法,就是补或一个打断异常,InterruptedException,或者抛出一个运行时异常,就能停止这个线程。

总结:对于web应用程序,异常释放锁的情况,如果不及时处理,很可能对你的应用程序业务逻辑产生严重的错误,比如你现在执行一个队列任务,很多对象都去在等待第一个对象正确执行完毕再去释放锁,但是第一个对象由于异常的出现,导致业务逻辑没有正常执行完毕,就释放了锁,那么可想而知后续的对象执行的都是错误的逻辑。所以这一点一定要引起注意,在编写代码的时候,一定要考虑周全。

synchronized细节问题(一)的更多相关文章

  1. 5.并发编程-synchronized 细节说明

    并发编程-synchronized 细节说明 1. synchronized-锁重入 & 异常释放锁 说明 * 关键字synchronized 拥有锁重入的功能,也就是在使用synchroni ...

  2. 架构师养成记--3.synchronized细节问题

    一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而met ...

  3. synchronized细节问题

    一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而met ...

  4. synchronized细节问题(二)

    使用synchronized声明的方法在某些情况下是有弊端的,比如A线程调用同步的方法执行一个很长时间的任务,那么B线程就必须等待比较长的时间才能执行,这样的情况下,可以使用synchronized代 ...

  5. 同步中的四种锁synchronized、ReentrantLock、ReadWriteLock、StampedLock

    目录 1.synchronized同步锁 2.ReentrantLock重入锁 3.ReadWriteLock读写锁 4.StampedLock戳锁(目前没找到合适的名字,先这么叫吧...) 5.总结 ...

  6. 同步中的四种锁synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock

    为了更好的支持并发程序,JDK内部提供了多种锁.本文总结4种锁. 1.synchronized同步锁 使用: synchronized本质上就2种锁: 1.锁同步代码块 2.锁方法 可用object. ...

  7. 对象、对象监视器、同步队列、执行线程关系(synchronized的实现细节或原理)

    synchronized在使用的时候底层细节你了解吗,相信很多同学对细节很少关注:比如竞争失败了的线程怎么安置,每个对象的监视器,线程执行synchronized时,其实是获取对象的监视器才能进入同步 ...

  8. java线程之——synchronized的注意细节

    我在学习synchronized的时候,十分好奇当一个线程进入了一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 然后就做了个实验(实验代码最后贴出),最后得到了如下 ...

  9. Java语法细节 - synchronized和volatile

    目录 synchronized关键字 关键字volatile synchronized关键字 synchronized关键字锁住方法和this的不同之处: public synchronized vo ...

随机推荐

  1. JSdom操作内容,样式,属性

    <p> JavaScript 能够直接写入 HTML 输出流中: </p> <script> document.write("<h1>This ...

  2. 使用原生js实现前端分页功能

    背景: 从后台提取出来数据,在前端进行分页. 代码: user-manage.js window.onload = function(){ var result = { message : " ...

  3. pycharm 对数据库进行可视化操作

    https://blog.csdn.net/qq_24189933/article/details/75666243

  4. ReactiveX 学习笔记(8)错误处理和 To 操作符

    Error Handling Operators Operators to Convert Observables 本文的主题为对 Observable 进行错误处理的操作符以及转换 Observab ...

  5. ArcGIS案例学习笔记4_2_城乡规划容积率计算和建筑景观三维动画

    ArcGIS案例学习笔记4_2_城乡规划容积率计算和建筑景观三维动画 概述 计划时间:第4天下午 目的:城市规划容积率计算和建筑三维景观动画 教程: pdf page578 数据:实验数据\Chp13 ...

  6. asp.net4.0

    asp.net4.0安装路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i

  7. EF 1

    安装框架: 在NuGet中安装ef框架,命令:Install-package EntityFramework 数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migratio ...

  8. Ubuntu Spark 环境搭建(转)

    在安装Spark之前,我们需要在自己的系统当中先安装上jdk和scala 可以去相应的官网上下载: JDK:http://www.oracle.com/technetwork/java/javase/ ...

  9. How to fix the bug “Expected "required", "optional", or "repeated".”?

    参考:https://github.com/tensorflow/models/issues/1834 You need to download protoc version 3.3 (already ...

  10. java-学习8

    方法的声明及使用 public class function { public static void main(String[] args) { printInfo();//调用printInfo( ...