天天看點

JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)

文章目錄

  • ​​1、公平鎖、非公平鎖​​
  • ​​2、可重入鎖​​
  • ​​3、自旋鎖​​
  • ​​4、死鎖​​

1、公平鎖、非公平鎖

公平鎖:非常公平、不能插隊、必須先來後到

  • 非公平鎖:非常不公平、可以插隊、(預設非公平)
  • JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)
  • 可以修改為公平鎖
  • JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)

2、可重入鎖

拿到外邊的鎖、就會自動拿到裡邊的鎖。

package com.lock;

/**
 * synchronized
 */
public class Demo1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.sms();
        },"A").start();

        new Thread(()->{
            phone.sms();
        },"B").start();
    }
}

class Phone{

    public synchronized void sms(){
        System.out.println(Thread.currentThread().getName()+"sms");
        call();
    }

    public synchronized  void call(){
        System.out.println(Thread.currentThread().getName()+"call");

    }
}
      

使用lock鎖

package com.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * synchronized
 */
public class Demo1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.sms();
        },"A").start();

        new Thread(()->{
            phone.sms();
        },"B").start();
    }
}

class Phone{

    Lock lock = new ReentrantLock();

    public  void sms(){
        lock.lock();

        try {
            System.out.println(Thread.currentThread().getName()+"sms");
            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、自旋鎖

spinlock

JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)

自己寫自旋鎖

package com.lock;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

public class SpinLockDemo {

   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);

    }


}
      
package com.lock;

import java.util.concurrent.TimeUnit;

public class Test {

    public static void main(String[] args) {
        SpinLockDemo spinLockDemo = new SpinLockDemo();

        new Thread(()->{
            spinLockDemo.mylock();

            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                spinLockDemo.myunlock();
            }

        },"A").start();



        new Thread(()->{
            spinLockDemo.mylock();
            try {
                System.out.println();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                spinLockDemo.myunlock();
            }

        },"B").start();
    }
}
      
JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)

4、死鎖

package com.lock;

import java.util.concurrent.TimeUnit;

public class DeadLockDemo {
    public static void main(String[] args) {
        String lockA="lockA";
        String lockB ="lockB";

        new Thread(new MyThread(lockA,lockB),"T1").start();
        new Thread(new MyThread(lockB,lockA),"T2").start();
    }

}

class MyThread implements Runnable{
    private String lockA;
    private String lockB;

    public MyThread(String lockA,String lockB){
        this.lockA = lockA;
        this.lockB =lockB;
    }


    @Override
    public void run() {
        synchronized (lockA){
            System.out.println(Thread.currentThread().getName()+"lock:"+lockA+"==>"+lockB);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB){
                System.out.println(Thread.currentThread().getName()+"lock:"+lockB+"==>"+lockA);

            }
        }
    }
}
      

測試

JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)

1、使用jps定位程序号​

​jps -l​

JUC(11)各種鎖的了解(公平鎖、可重入鎖、自旋鎖、死鎖)