天天看點

java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)

1.公平鎖、非公平鎖

java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)
java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)

2.可重入鎖(遞歸鎖)

java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)

3.自旋鎖

java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)

下面代碼5秒鐘自旋了10萬次,還是很消耗CPU的

java -鎖(公平、非公平鎖、可重入鎖【遞歸鎖】、自旋鎖)1.公平鎖、非公平鎖2.可重入鎖(遞歸鎖)3.自旋鎖4.獨占鎖(寫鎖)|共享鎖(讀鎖)
package HighConcurrency;

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

public class SpinLockDemo {
    //原子引用線程
    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()+"線程自旋。。。");
        }
    }

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

        SpinLockDemo spinLockDemo = new SpinLockDemo();
        new Thread(()->{
            spinLockDemo.myLock();
            //暫停線程一會
            try {TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            spinLockDemo.myunLock();
        },"AA").start();

        try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

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

            spinLockDemo.myunLock();
        },"BB").start();
    }
}

           

4.獨占鎖(寫鎖)|共享鎖(讀鎖)

獨占鎖:指該鎖一次隻能被一個線程持有,ReentrantLock和synchronized都是獨占鎖

共享鎖:可被多個線程所持有。對ReentrantReadWriteLock其讀鎖是共享鎖,其寫鎖是獨占鎖。

讀鎖的共享鎖可保證高并發讀是非常都效的

class MyCache{ //資源類
    private volatile Map<String,Object> map = new HashMap<>();

    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

    //寫緩存架構,讀、寫、清空
    public void get(String key,Object value){ //讀
        rwLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "\t 正在讀取:");
            try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
            Object object = map.get(key);
            System.out.println(Thread.currentThread().getName() + "\t 讀取完成" + object);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            rwLock.readLock().unlock();
        }
    }

    public void put(String key,Object value){ //寫

        rwLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在寫入" + key);
            try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(Thread.currentThread().getName()+"\t 寫入完成");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            rwLock.writeLock().unlock();
        }
    }

}
public class ReadWriteLockDemo {
    public static void main(String[] args) {

        MyCache myCache = new MyCache();
        //線程操作資源類
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(() -> {
                myCache.put(tempInt+"",tempInt+"");
            },"線程"+String.valueOf(i)).start();
        }
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(() -> {
                myCache.get(tempInt+"",tempInt+"");
            },"線程"+String.valueOf(i)).start();
        }
    }
}