1.公平锁,非公平锁
公平锁: 非常公平,不能插队,必须先来后到
非公平锁: 非常不公平,可以插队,默认是非公平
Lock lock = new ReentrantLock(true);
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
2.可重复锁
synchronized 拿一把锁 会把里面的锁也拿到
public class lock3 {
public static void main(String[] args) {
Phone1 phone = new Phone1();
new Thread(()->{phone.sendSms();},"A").start();
new Thread(()->{phone.hello();},"B").start();
}
}
class Phone1{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
public void hello(){
System.out.println("hello");
}
}
lock
public class Lock5 {
public static void main(String[] args) {
Phone3 phone = new Phone3();
new Thread(() -> {
phone.sendSms();
}, "A").start();
new Thread(() -> {
phone.sendSms();
}, "B").start();
}
}
class Phone3 {
Lock lock = new ReentrantLock();
public void sendSms() {
lock.lock();//这里需要注意 , 几个lock()加锁动作就需要对应几个unlock()解锁,一把锁一把钥匙 ,这是和synchronized不一样的地方
//lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "sendSms 发短信");
call();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void call() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "call 打电话");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
3.自旋锁
不断循环 ,知道成功为止
public class SpinlockTest {
/**
* 自定义 自旋锁
*/
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "- mylock");
while (atomicReference.compareAndSet(null, thread)) {
}
}
public void myUnLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "- myUnLock");
atomicReference.compareAndSet(thread, null);
}
/**
* 测试
*
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
SpinlockTest spinlockTest = new SpinlockTest();
new Thread(() -> {
spinlockTest.myLock();
try {
TimeUnit.SECONDS.sleep(2);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinlockTest.myUnLock();
}
}, "aa").start();
TimeUnit.SECONDS.sleep(5);
new Thread(() -> {
spinlockTest.myLock();
try {
TimeUnit.SECONDS.sleep(2);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinlockTest.myUnLock();
}
}, "bb").start();
}
}
4.死锁
public class DeadLock {
public static void main(String[] args) {
String resourceA = "resourceA";
String resourceB = "resourceB";
new Thread(new MyThread(resourceA,resourceB),"T1").start();
new Thread(new MyThread(resourceB,resourceA),"T2").start();
}
}
class MyThread implements Runnable{
private String resourceA;
private String resourceB;
public MyThread(String resourceA, String resourceB) {
this.resourceA = resourceA;
this.resourceB = resourceB;
}
@Override
public void run() {
synchronized (resourceA){
System.out.println(Thread.currentThread().getName()+"resourceA get resourceB");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceB){
System.out.println(Thread.currentThread().getName()+"resourceB get resourceA");
}
}
}
}
排除死锁的方法:
使用 jps -l 定位进程号
使用 jstack 进程号 找到问题