synchronized锁重入
- package synLockIn_1;
- /* synchronized锁重入,当一个线程得到一个对象锁且还未释放锁时,再次请求此对象锁时可以再次得到该对象的锁
- * 此例中线程1进入Service类的service_1方式时,得到了Lock锁,在这个方法内便可以再次访问service_2方法
- * 而此时由于对象锁没被释放,线程2无法访问service_1方法*/
- class Service{
- synchronized public void service1(){
- System.out.println(Thread.currentThread().getName()+" service_1");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- service2();
- }
- synchronized public void service2(){
- System.out.println(Thread.currentThread().getName()+" service_2");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- service3();
- }
- synchronized public void service3(){
- System.out.println(Thread.currentThread().getName()+" service_3");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
- class MyThread extends Thread{
- Service service;
- public MyThread(Service service){
- this.service = service;
- }
- @Override
- public void run(){
- service.service1();
- }
- }
- public class Run {
- public static void main(String[] args) {
- Service service = new Service(); //两个线程共享同一个Service对象,使得两个线程访问一个对象,JVM只产生一个对象锁
- MyThread t = new MyThread(service);
- t.start();
- MyThread t1 = new MyThread(service);
- t1.start();
- }
- }
运行结果如下

从运行结果中可以看出线程Thread-1先访问了service_1同步方法,输出Thread-1 service_1后停留1秒。对象锁还没释放,且两个线程共享同一个类,所以线程Thread-0无法访问service_1方法。而Thread-1还没释放对象锁,但可以重新获得对象锁继续访问service_2同步方法。
可重入锁也支持在父子类继承的环境中。
- package synLockIn2;
- /* synchronized锁重入,当一个线程得到一个对象锁且还未释放锁时,再次请求此对象锁时可以再次得到该对象的锁 */
- class Main {
- public int i = 10;
- synchronized public void operateIMainMethod(){
- try{
- System.out.println( Thread.currentThread().getName()+" main print i="+i);
- i--;
- Thread.sleep(100);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
- class Sub extends Main {
- synchronized public void operateIMainMethod(){
- System.out.println(Thread.currentThread().getName()+" 线程开始!!");
- try{
- while( i > 0 ){
- System.out.println( Thread.currentThread().getName()+" sub print i=" + i);
- i--;
- Thread.sleep(100);
- super.operateIMainMethod();
- }
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName()+" 线程结束!!");
- }
- }
- class MyThread extends Thread{
- Sub sub = new Sub();
- MyThread(Sub sub){
- this.sub = sub;
- }
- @Override
- public void run(){
- sub.operateIMainMethod();
- }
- }
- public class Run {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Sub sub = new Sub();
- MyThread t = new MyThread(sub);
- t.start();
- MyThread t1 = new MyThread(sub);
- t1.start();
- }
- }
运行结果如下:

从结果可以看出线程Thread-0先访问子类的同步方法operateIMainMethod,输入Thread-0 sub print i=10,然后在还未释放对象锁的情况下重新获得对象锁访问父类的同步方法operateIMainMethod,输出Thread-0 main print i=9,然后进入下一个循环。
线程Thread-0访问结束释放对象锁后,线程Thread-1开始访问。由于共享同一个对象且i在同步方法operateIMainMethod()外被定义,所以当线程Thread-1访问时i已经为零。
synchronized锁重入的更多相关文章
- 深入理解Java中的synchronized锁重入
问题导入:如果一个线程调用了一个对象的同步方法,那么他还能不能在调用这个对象的另外一个同步方法呢? 这里就是synchronized锁重入问题. 一.synchronized锁重入 来看下面的代码: ...
- 5.synchronized锁重入
package demo1; /** * synchronized锁重入 * Created by liudan on 2017/6/5. */ public class MyThread5_sync ...
- Java 学习笔记之 Synchronized锁重入
Synchronized锁重入: 当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁.这也证明在一个Synchronized方法/块的内部调用本类的其他Synchronized方法 ...
- Java并发编程原理与实战十一:锁重入&自旋锁&死锁
一.锁重入 package com.roocon.thread.t6; public class Demo { /* 当第一个线程A拿到当前实例锁后,进入a方法,那么,线程A还能拿到被当前实例所加锁的 ...
- synchronized的重入
/** * synchronized的重入 * */ public class SyncDubbo1 { public synchronized void method1(){ System.out. ...
- 浅谈Java中的锁:Synchronized、重入锁、读写锁
Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...
- java的synchronized可重入锁
在java内部,同一线程在调用自己类中其他synchronized方法/块或调用父类的synchronized方法/块都不会阻碍该线程的执行,就是说同一线程对同一个对象锁是可重入的,而且同一个线程可以 ...
- Synchronized可重入锁通俗易懂的简单分析
可重入锁概念: 当一个线程得到一个对象锁后,再次请求此对象时时可以再次得到该对象的锁的,这也证明synchronized方法/块的内部调用本类的其他synchronized方法/块时,时永远可以得到锁 ...
- Synchronized可重入锁分析
可重入锁又称递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象必须是同一对象或者class), 不会因为之前已经获取过还没实方而发生阻塞.即同一线程可执行 ...
随机推荐
- Linux-TCP Queue的一些问题
先来回顾下三次握手里面涉及到的问题:1. 当 client 通过 connect 向 server 发出 SYN 包时,client 会维护一个 socket 等待队列,而 server 会维护一个 ...
- LeetCode---Binary Search
475. Heaters 思路:每趟循环查找离房子最近的热水器,计算距离,最后取最大距离 public int findRadius(int[] houses, int[] heaters) { Ar ...
- gRaphael——JavaScript 矢量图表库:两行代码实现精美图表
gRaphael 是一个致力于帮助开发人员在网页中绘制各种精美图表的 Javascript 库,基于强大的 Raphael 矢量图形库.你只需要编写几行简单的代码就能创建出精美的条形图.饼图.点图和曲 ...
- CSS 后代选择器
后代选择器(descendant selector)又称为包含选择器. 后代选择器可以选择作为某元素后代的元素. 根据上下文选择元素 我们可以定义后代选择器来创建一些规则,使这些规则在某些文档结构中起 ...
- C++中利用数组对字符进行除重和排序
题目:随机输入一组字符,对这组字符进行除重和排序输出, 例如:输入aafddbc 输出:abcdf 程序: #include "stdafx.h"#include<iostr ...
- Lua学习----Lua基础数据类型
前言 Lua有6中数据类型,分别是nil(空).boolean(布尔).number(数字).string(字符).table(表).function(函数) 在Lua中可以使用type函数来返回一个 ...
- Install Houdini 12.5 x64 in CentOS 7
Thanks for Must(QQ ID)'s big help for installing Houdini in CentOS7. - download HOUDINI_FX_V12.5.371 ...
- C语言函数指针实验
上次看Atmel的示例工程,发现人家使用了函数指针的结构体(函数指针结构体).感叹人家的C语言功夫审核,自己费劲还是只能读懂的份.不过,函数指针确实好用.今天就试试这个超牛的东西.Now let's ...
- WebApi 学习随笔(一)
引用MSDN: ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad ...
- 配置管理服务diamond和disconf横向对比
Diamond则是淘宝开源的一种分布式配置管理服务的实现 disconf是来自百度的分布式配置管理平台,包括百度.滴滴出行.银联.网易.拉勾网.苏宁易购.顺丰科技 等知名互联网公司正在使用! 对比项目 ...