package com.shi.lock;
/**
* 可重入锁 (递归锁)
* 指的是同一个线程获得锁以后,内层递归函数仍然能获得该锁的代码,
* 再同一个线程再外层获得锁的时候,在进入内层方法会自动获取锁
* @author shiye
*
*结果:
线程A sedSMS() 被调用....
线程A sedEmail() 被调用....
线程A play() 被调用....
线程B sedSMS() 被调用....
线程B sedEmail() 被调用....
线程B play() 被调用....
*/
public class TestLock1 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread( () -> {
phone.sedSMS();
},"线程A ").start();
new Thread( () -> {
phone.sedSMS();
},"线程B ").start();
}
}
class Phone{
public synchronized void sedSMS() {
System.out.println(Thread.currentThread().getName() + " \t sedSMS() 被调用.... " );
sedEmail();
}
public synchronized void sedEmail() {
System.out.println(Thread.currentThread().getName() + " \t sedEmail() 被调用.... " );
Phone.play();
}
public static synchronized void play() {
System.out.println(Thread.currentThread().getName() + " \t play() 被调用.... " );
}
}
自旋锁
package com.shi.lock;
import java.util.concurrent.atomic.AtomicReference;
/**
* 自旋锁
* @author shiye
*
*运行结果:
线程A come in ...
线程B come in ...
线程B 请求获取锁
线程B 请求获取锁
线程B 请求获取锁
线程B 请求获取锁
线程B 请求获取锁
线程B 请求获取锁
线程B 请求获取锁
线程A invoked myUnlock
线程B invoked myUnlock
*/
public class TestSpinLock {
//原子应用
AtomicReference<Thread> atomicReference = new AtomicReference<>();
//自旋加锁
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() +"\t come in ...");
while(!atomicReference.compareAndSet(null, thread)) {
//自旋 直到获取当前锁
System.out.println(Thread.currentThread().getName() + "\t 请求获取锁" );
}
}
//自选解锁
public void myUnlock() {
Thread thread = Thread.currentThread();
atomicReference.compareAndSet(thread, null);//如果是当前线程就 解锁
System.out.println( Thread.currentThread().getName() + "\t invoked myUnlock");
}
public static void main(String[] args) throws InterruptedException {
TestSpinLock spinLock = new TestSpinLock();
new Thread(()-> {
spinLock.myLock();
try {
Thread.sleep(1100);
} catch (InterruptedException e) {
e.printStackTrace();
}
spinLock.myUnlock();
},"线程A ").start();
Thread.sleep(1000);
new Thread(()-> {
spinLock.myLock();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
spinLock.myUnlock();
},"线程B ").start();
}
}