JavaSE---多线程---锁---Lock

1、ReentrantLock

    1.1、可重入锁:  当 某个线程获得到某个锁,可以重复获取相同的锁 而不会 出现死锁;

    1.2、可重入锁: synchronized、ReentrantLock

package com.an.lock.reentrantlocks;

/**
 * @description:
 * @author: anpeiyong
 * @date: Created in 2020/6/10 13:51
 * @since:
 */
public class SynchronizedTest {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    System.out.println("第1次获取锁,这个锁是:" + this);
                    int index = 1;
                    while (true) {
                        synchronized (this) {
                            System.out.println("第" + (++index) + "次获取锁,这个锁是:" + this);
                        }
                        if (index == 10) {
                            break;
                        }
                    }
                }
            }
        }).start();
    }
}


结果:
第1次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第2次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第3次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第4次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第5次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第6次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第7次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第8次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第9次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第10次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d

 

package com.an.lock.reentrantlocks;

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

/**
 * @description: 获取锁、释放锁 需要匹配
 * @author: anpeiyong
 * @date: Created in 2020/6/10 13:53
 * @since:
 */
public class LockTest {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    System.out.println("第1次获取锁,这个锁是:" + lock);

                    int index = 1;
                    while (true) {
                        try {
                            lock.lock();
                            System.out.println("第" + (++index) + "次获取锁,这个锁是:" + lock);

                            try {
                                Thread.sleep(new Random().nextInt(200));
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            if (index == 10) {
                                break;
                            }
                        } finally {
                            lock.unlock();
                        }
                    }
                } finally {
                    lock.unlock();
                }
            }
        }).start();
    }
}


结果:
第1次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第2次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第3次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第4次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第5次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第6次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第7次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第8次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第9次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第10次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]

     1.3、ReentrantLock

      

      

      1.4、ReentrantLock内部类Sync

 

      

 

       

 

      

 

      1.5、AbstractQueuedSynchronizer

          组成:volatile修饰的state + 双向链表

          实现:

            自旋  、CAS 、LockSupport.park()|unpark()

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long stateOffset;
    private static final long headOffset;
    private static final long tailOffset;
    private static final long waitStatusOffset;
    private static final long nextOffset;

    static {
        try {
            stateOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
            headOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
            tailOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
            waitStatusOffset = unsafe.objectFieldOffset
                (Node.class.getDeclaredField("waitStatus"));
            nextOffset = unsafe.objectFieldOffset
                (Node.class.getDeclaredField("next"));

        } catch (Exception ex) { throw new Error(ex); }
    }
   
    static final class Node {
    
    }

    private transient volatile Node head;
    private transient volatile Node tail;
    private volatile int state;

    //默认非公平锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

}

         

2、ReentrantReadWriteLock

      

 

      

 

       

3、ReentrantLock的锁获取方式     

public class ReentrantLock implements Lock, java.io.Serializable {

    private final Sync sync;
  
    public void lock() {
        sync.lock();
    }

    abstract static class Sync extends AbstractQueuedSynchronizer {

       abstract void lock();

       final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    
    }

    static final class FairSync extends Sync {

        final void lock() {
            acquire(1);
        }


        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }


    static final class NonfairSync extends Sync {

       final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

    }

}


public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

    public final void acquire(int arg) {
        //tryAcquire()      acquireQueued()   轮询获取资源
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        //获取失败,当前线程中断
            selfInterrupt();
    }


    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // 快速插入
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        //常规插入
        enq(node);
        return node;
    }

     private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }


    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

     static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }

}

 

       3.2、可轮询

4、公平性

             按  线程之间   获取锁的顺序

    

    4.1、公平锁

        线程   顺序请求锁

    4.2、非公平锁

        线程 只有 在锁被占用时等待,允许跳跃获得锁

5、Lock与synchronized选择

    5.1、只有 synchronized  不能满足(比如 可定时锁、公平锁、可中断锁 )使用时,才使用 Lock,否则,推荐synchronized ; 

6、ReadWriteLock

    6.1、一个资源 同时   被多个线程读取  且  只被一个线程写入; 

    6.2、读写锁能够提供更好的并发性;

7、ReentrantReadWriteLock

    7.1、

public interface ReadWriteLock {

    Lock readLock();
    Lock writeLock();

}



public class ReentrantReadWriteLock
        implements ReadWriteLock, java.io.Serializable {

     final Sync sync; 

     abstract static class Sync extends AbstractQueuedSynchronizer {}

     static final class NonfairSync extends Sync {}

     static final class FairSync extends Sync {}

     public static class ReadLock implements Lock, java.io.Serializable {}

     public static class WriteLock implements Lock, java.io.Serializable {}

}

 

    

 

posted on 2020-06-10 14:16  anpeiyong  阅读(227)  评论(0)    收藏  举报

导航