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), 不会因为之前已经获取过还没实方而发生阻塞.即同一线程可执行 ...
随机推荐
- jquery属性的操作
HTML示例代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- geohash-net实现
基于c#语言 geohash算法基本实现源码,参见: https://github.com/sharonjl/geohash-net , 源码中具体包含如下方法: String CalculateAd ...
- 【转】libevent源码分析
libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...
- 如何比较两个SQL数据库的字段差别。
程序好几个版本了,数据也弄出好好几版本,这下好了,原程序要升级,当然数据库也要升,可是里面已经有了大量的数据了,这时候怎么办.写了个存储过程来解决,一目了然. 因为2005及以上的数据库已经没有表sy ...
- HttpClientUtil [使用apache httpclient模拟http请求]
基于httpclient-4.5.2 模拟http请求 以get/post方式发送json请求,并获取服务器返回的json -------------------------------------- ...
- 01 Linux入门介绍
一.Linux 初步介绍 Linux的优点 免费的,开源的 支持多线程,多用户 安全性好 对内存和文件管理优越 系统稳定 消耗资源少 Linux的缺点 操作相对困难 一些专业软件以及游戏支持度不足 L ...
- pc wap 判断浏览器ua属性
var ua = navigator.userAgent.toLowerCase(); var Android = String(ua.match(/android/i)) == "andr ...
- xcode中使用xib添加autolayout中constrain to margins的不同
在使用xcode7 在storyboard中添加autolayout中发现 如果添加在view 直接添加到viewcontroller的view 上 constrain to margins 只 ...
- SQL Server中可能为null的变量逻辑运算的时候要小心
DECLARE @a int declare @b int IF(@a<>@b) print('@a<>@b') else print('@a=@b') ) print('b& ...
- 设置树莓派3 B+的静态IP
修改/etc/dhcpcd.conf 文件 sudo vim /etc/dhcpcd.conf interface eth0 static ip_address= static routers=192 ...