synchronized重入锁

/ 多线程 / 没有评论 / 295浏览

我们知道当线程访问一个synchronized方法时就会获取到这个对象的锁,如果线程没有执行完,这个锁就一直不会释放,也就是说这时其它线程在访问synchronized方法时是获取不到锁的。但这里面有一个前提就是其它线程是获取不到锁的,那已经获取到锁的线程在获取锁那会是什么情况呢?事实上如果是已经获取到锁的线程在次获取锁那么它依然可以获取成功。这就是synchronized的重入锁的本质。自己可以再次获取自己的内部锁就叫重入锁。我们看下面的实例来演示synchronized的重入锁。

/**
* 用户登录
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo {

public synchronized void login1() {
System.out.println(String.format("login: %s\tthread: %s", "login1", Thread.currentThread().getName()));
login2();
}

public synchronized void login2() {
System.out.println(String.format("login: %s\tthread: %s", "login2", Thread.currentThread().getName()));
login3();
}

public synchronized void login3() {
System.out.println(String.format("login: %s\tthread: %s", "login3", Thread.currentThread().getName()));
}

}
/**
* 用户请求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestUser extends Thread {

@Override
public void run() {
Userinfo userinfo = new Userinfo();
userinfo.login1();
}
}
/**
* 测试类
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:49
* @since 1.0.0
*/
public class RequestRun {
public static void main(String[] args) {
RequestUser requestUser = new RequestUser();
requestUser.start();
}
}
login: login1	thread: Thread-0
login: login2	thread: Thread-0
login: login3	thread: Thread-0

我们看信息程序里的方法都执行了,说明当前线程是可以重新获取到自己的锁的,也就是重入锁,如果没有重入锁的话,那么上面的程序就会出现死锁现象。重入锁除了在当前类中存在,在父子类继承中也是存在的。

/**
* 消息生产者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:31
* @since 1.0.0
*/
public class Message {

public int i = 10;

public synchronized void run() {
try {
i--;
System.out.println(String.format("父类 i: %s\tthread: %s", i, Thread.currentThread().getName()));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 消息生产者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:31
* @since 1.0.0
*/
public class MessageServer extends Message {

@Override
public void run() {
try {
while (i > 0) {
i--;
System.out.println(String.format("子类 i: %s\tthread: %s", i, Thread.currentThread().getName()));
Thread.sleep(100);
super.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 测试类
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:49
* @since 1.0.0
*/
public class RequestRun {
public static void main(String[] args) {
RequestUser requestUser = new RequestUser();
requestUser.start();
}
}
子类 i: 9	thread: Thread-0
父类 i: 8	thread: Thread-0
子类 i: 7	thread: Thread-0
父类 i: 6	thread: Thread-0
子类 i: 5	thread: Thread-0
父类 i: 4	thread: Thread-0
子类 i: 3	thread: Thread-0
父类 i: 2	thread: Thread-0
子类 i: 1	thread: Thread-0
父类 i: 0	thread: Thread-0

我们看到子类也是可以调用父类的synchronized方法的,这就说明在继承中也是存在synchronized重入锁的。