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), 不会因为之前已经获取过还没实方而发生阻塞.即同一线程可执行 ...
随机推荐
- 10天学会phpWeChat——第三天:从数据库读取数据到视图
在第二天,我们创建了我们的第一个phpWeChat功能模块,但是比较简单.实际生产环境中,我们不可能有如此简单的需求.更多的情况是数据存储在MySql数据库中,我们开发功能模块的作用就是将这些数据从M ...
- mongo安全:增加用户名密码
0.简述:在非auth下创建账户,然后重启 1.以不需要用户名密码的方式启动mongodb 2.运行客户端mongo,输入以下指令 show dbs;use admin;db.createRole({ ...
- HashMap 与 HashTable的区别
1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样.可以用synchronized实现HashMap ...
- SSL安全证书-概念解析
一.关于证书 数字证书是一种认证机制.简单点说,它代表了一种由权威机构颁发授权的安全标志. 由来 在以前,传统网站采用HTTP协议进行数据传输,所有的数据几乎都用的明文,很容易发生隐私泄露.为了解决安 ...
- js 中isArray
es5中新加的方法Array.isArray是否是数值,低版本浏览器中可以这样修复 if (!Array.isArray) { Array.isArray = function(arg) { retu ...
- 显示intent和隐示intent有什么区别
显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent. 隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent. 说明:And ...
- linux下重置mysql的root密码
# /etc/init.d/mysql stop # mysqld_safe --user=mysql --skip-grant-tables --skip-networking & # my ...
- Android线程间通信更新UI的方法(重点分析EventBus)
Android的UI更新只能在UI线程中,即主线程.子线程中如果要进行UI更新,都是要通知主线程来进行. 几种实现方式总结如下,欢迎补充. 1.runOnUiThread() 子线程中持有当前Acti ...
- 【学】AngularJS日记(3)- $apply(), run()方法
$scope.$apply()方法可以强制$apply()里运行的函数所改变的model里的数据直接反应到view里,因为在angular的环境中,有时会用到原生js或者jquery的时候,这些行为有 ...
- [AS3.0] HTMLLoader与js交互
HtmlLoader 的属性window是加载到 HTML 控件中的内容的全局 JavaScript 对象,通过这个对象能够方便的和页面js通讯. AS代码: import flash.html.HT ...