公平锁
是指多个线程按照申请锁的顺序来获取锁,类似排队打饭,先来后到。
是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。在高并发的情况下,有可能造成优先级反转或者饥饿现象。
reentrantlock默认是非公平锁,但是可以设置为true成为公平锁,synchonized也是非公平锁。
指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。
线程可以进入任何一个它已经拥有的锁所同步着的代码块。
最大作用:避免死锁
reentrantlock和synchonized都是可重入锁。
public class synchronzieddemo {
private synchronized void print() {
doadd();
}
private synchronized void doadd() {
system.out.println("doadd...");
}
public static void main(string[] args) {
synchronzieddemo synchronzieddemo = new synchronzieddemo();
synchronzieddemo.print(); // doadd...
}
}
public class reentrantlockdemo {
private lock lock = new reentrantlock();
private void print() {
lock.lock();
doadd();
lock.unlock();
}
private void doadd() {
lock.lock();
lock.lock();
system.out.println("doadd...");
lock.unlock();
lock.unlock();
}
public static void main(string[] args) {
reentrantlockdemo reentrantlockdemo = new reentrantlockdemo();
reentrantlockdemo.print();
}
}
注意:lock.lock();和lock.unlock();个数匹配,多少个锁都可以正常运行,若是不匹配,则程序运行卡死。
指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,好处是减少线程上下文切换的消耗,缺点是循环会消耗cpu。
手动实行自旋锁
public class spinlock {
private atomicreference atomicreference = new atomicreference<>();
private void lock () {
system.out.println(thread.currentthread() " coming...");
while (!atomicreference.compareandset(null, thread.currentthread())) {
// loop
}
}
private void unlock() {
thread thread = thread.currentthread();
atomicreference.compareandset(thread, null);
system.out.println(thread " unlock...");
}
public static void main(string[] args) throws interruptedexception {
spinlock spinlock = new spinlock();
new thread(() -> {
spinlock.lock();
try {
thread.sleep(3000);
} catch (interruptedexception e) {
e.printstacktrace();
}
system.out.println("hahaha");
spinlock.unlock();
}).start();
thread.sleep(1);
new thread(() -> {
spinlock.lock();
system.out.println("hehehe");
spinlock.unlock();
}).start();
}
}