java-synchronized 嵌套使用代码详解

当synchronized使用过多时,可能会造成死锁,那么死锁到底是怎么一回事呢。先看下面的代码,实现死锁

//死锁的实现
classA
{
publicvoidget(){
System.out.println("A说:我开始启动了,B,给我你的资源");
}
publicvoidsay(){
System.out.println("A获得资源");
}
}
classB
{
publicvoidget(){
System.out.println("B说:我开始启动了,A,给我你的资源");
}
publicvoidsay(){
System.out.println("B获得资源");
}
}
classMyThreadimplementsRunnable
{
publicstaticAa=newA();
publicstaticBb=newB();
publicbooleanflag=false;
publicvoidrun(){
if(flag){
synchronized(a){
a.get();
try{
Thread.sleep(500);
}catch(InterruptedExceptione){}
synchronized(b){ //此同步代码块在另一同步代码块里
a.say();
}
}
}else{
synchronized(b){
b.get();
try{
Thread.sleep(500);
}catch(InterruptedExceptione){}
synchronized(a){ //此同步代码块在另一同步代码块里
b.say();
}
}
}
}
}
publicclassDemo24
{
publicstaticvoidmain(Stringargs[]){
MyThreadmt1=newMyThread();
MyThreadmt2=newMyThread();
mt1.flag=true;
mt2.flag=false;
Threadth1=newThread(mt1);
Threadth2=newThread(mt2);
th1.start();
th2.start();
}
}

以上代码由于 synchronized 的同步造成了死锁,死锁是两个或多个线程同时等待对方的完成,而程序无法继续执行。在解释代码前,首先要明白synchronized到底是怎么一回事。synchronized 定义同步,那么同步的什么,什么和什么同步了?

首先,我们得知道,什么是。在java中,每一个对象都有一个内部锁,如果以方法或代码块用 synchronized 进行声明,那么对象的锁将保护整个方法或代码块,要调用这个方法或者执行这个代码块,必须获得这个对象的。而且,任何时候都只能有一个线程对象执行被保护的代码

在以上代码中,在线程th1启动后,他就获得了a的锁,同时当其休眠完毕,求会申请获得b的锁,而此时,他的a锁没有放弃。在线程th2启动后,他就获得了b的锁,同时当其休眠完毕,求会申请获得a的锁,而此时,他的b锁没有放弃。

两方都握有自己的锁不放弃,而同时申请另一方的锁,所以,此时就造成了死锁

同步,同步的就是线程和对象,将线程和对象进行绑定,获取对象的锁。

注意:通过以上代码可以发现,死锁的必要条件是不放弃已有的锁,而同时申请新锁。所以,要想实现死锁,就会有synchronized的嵌套。

这样才能同时操作两个以上的锁,从而造成死锁

总结

以上就是本文关于java-synchronized 嵌套使用代码详解的全部内容,希望对大家有所帮助。

(0)

相关推荐

  • java synchronized同步静态方法和同步非静态方法的异同

    java synchronized 详解 synchronized关键字有两种用法,一种是只用于方法的定义中,另外一种是synchronized块,我们不仅可以使用synchronized来同步一个对象变量,你也可以通synchronizedl来同步类中的静态方法和非静态方法. synchronized块的语法如下: public void method() { synchronized(表达式) { } } public void method() { synchronized(表达式) {

  • java中synchronized(同步代码块和同步方法)详解及区别

     java中synchronized(同步代码块和同步方法)详解及区别 问题的由来: 看到这样一个面试题: //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized (obj){} } synchronized用于解决同步问题,当有多条线程同时访问共享数据时,如果进行同步,就会发生错误,Java提供的解决方案是:只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他

  • Java 同步锁(synchronized)详解及实例

    Java 同步锁(synchronized)详解及实例 Java中cpu分给每个线程的时间片是随机的并且在Java中好多都是多个线程共用一个资源,比如火车卖票,火车票是一定的,但卖火车票的窗口到处都有,每个窗口就相当于一个线程,这么多的线程共用所有的火车票这个资源.如果在一个时间点上,两个线程同时使用这个资源,那他们取出的火车票是一样的(座位号一样),这样就会给乘客造成麻烦.比如下面程序: package com.pakage.ThreadAndRunnable; public class Ru

  • 解决Maven 项目报错 java.httpservlet和synchronized使用方法

    使用java8 的lanmbe表达式时,使用java1.8编译,则会报错 需要在pom.xml的<bulid></build>中添加 <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</versi

  • java-synchronized 嵌套使用代码详解

    当synchronized使用过多时,可能会造成死锁,那么死锁到底是怎么一回事呢.先看下面的代码,实现死锁: //死锁的实现 classA { publicvoidget(){ System.out.println("A说:我开始启动了,B,给我你的资源"); } publicvoidsay(){ System.out.println("A获得资源"); } } classB { publicvoidget(){ System.out.println("B

  • 通过反射实现Java下的委托机制代码详解

    简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并实现委托方法 //添加一个静态方法委托,返回整型值ID代表该方法与参数构成的实例.若失败,则返回-1. public synchronized int addFunctionDelegate(Class<?> srcClass,String methodName,Object... params)

  • Java Synchronized锁的使用详解

    目录 Synchronized的用法 同步示例方法 同步静态方法 同步代码块 Synchronized的用法 在多线程并发问题中,常用Synchronized锁解决问题.Synchronized锁通常用于同步示例方法,同步静态方法,同步代码块等. 同步示例方法 我们可能自己使用过在方法前加Synchronized锁修饰,在多线程并发同时调用同一个实例化对象时,如果这个方法加上了Synchronized锁,那么也是线程安全的.举个栗子: package Thread; import java.ut

  • Java回调函数实例代码详解

    首先说说什么叫回调函数? 在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调.在调用接口时,需要严格的按照定义的参数和方法调用,并且需要处理函数的异步,否则会导致程序的崩溃. 这样的解释似乎还是比较难懂,这里举个简 单的例子: 程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法.目的达到

  • java实现队列数据结构代码详解

    什么是队列结构 一种线性结构,具有特殊的运算法则[只能在一端(队头)删除,在另一端(队尾)插入]. 分类: 顺序队列结构 链式队列结构 基本操作: 入队列 出队列 给出一些应用队列的场景 1):当作业被送到打印机的时候,就可以按到达的顺序排起来,因此每一份作业是队列的节点. 2):售票口的人买票的顺序的按照先来先买的顺序售票. 3):当所有的终端被占用,由于资源有限,来访请求需要放在一个队列中等候. 队列是先进先出的! 我们设置一个叫做LinkQueue<T>的泛型集合类,该类里面有 Node

  • java内部测试类代码详解

    我们一般使用的java内部类有4种形式:一般内部类.局部内部类.匿名内部类.静态内部类.以下是我作的一个测试,以说明各种内部类的特性. 有关内部类的特性,代码中有详细说明,如下. /* * java内部类测试 * * InterObj反射结果: * * private int i * private InterObj$InterA ia * public InterObj() * public static void main(java.lang.String[]) * private int

  • Java编程复用类代码详解

    本文研究的主要是Java编程中的复用类,那么到底复用类是什么东西,又有什么用法,下面具体介绍. 看了老罗罗升阳的专访,情不自禁地佩服,很年轻,我之前以为和罗永浩一个级别的年龄,也是见过的不是初高中编程的一位大牛之一,专访之后,发现老罗也是一步一个脚印的人.别说什么难做,做不了,你根本就没去尝试,也没有去坚持. If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but whateve

  • 一个通用的Java分页基类代码详解

    分页的基类 import java.util.List; /** * 分页显示的标准类,基本操作,是先给予-当前页数一共的数据条数-每页显示的条数, * 然后在初始化该类,得到总共页数,和开始序号和结束序号, * 然后数据库分页用到开始序号和结束序号,得到数据集合后赋值给该类的list属性, * * 然后把该类发送到jsp页面,进行访问 * @author admin * * @param <T> */ public class PageBean<T> { private int

  • Java中可变长度参数代码详解

    到J2SE1.4为止,一直无法在Java程序里定义实参个数可变的方法--因为Java要求实参(Arguments)和形参(Parameters)的数量和类型都必须逐一匹配,而形参的数目是在定义方法时就已经固定下来了.尽管可以通过重载机制,为同一个方法提供带有不同数量的形参的版本,但是这仍然不能达到让实参数量任意变化的目的. 然而,有些方法的语义要求它们必须能接受个数可变的实参--例如著名的main方法,就需要能接受所有的命令行参数为实参,而命令行参数的数目,事先根本无法确定下来. 对于这个问题,

  • Java实现搜索功能代码详解

    首先,我们要清楚搜索框中根据关键字进行条件搜索发送的是Get请求,并且是向当前页面发送Get请求 //示例代码 请求路径为当前页面路径 "/product" <!-- 搜索框 get请求 根据商品名称的关键字进行搜索--> <form action="/product" class="form-inline pull-left" > <input type="text" name="pr

随机推荐