java并发编程---ReentrantLock不可打断模式与可打断模式

文章目录

  • ReentrantLock不可打断模式
  • 可打断模式

ReentrantLock不可打断模式

在此模式下,即使它被打断,仍会驻留在AQS队列中,等获得锁后方能继续运行(是继续运行!只是打断标记被设置为true)

    public ReentrantLock() {
     
        sync = new NonfairSync();
    }
    public void lock() {
     
        sync.lock();
    }
static final class NonfairSync extends Sync {
     

java并发编程---ReentrantLock不可打断模式与可打断模式_第1张图片

lock,重点方法

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

acquire方法

    public final void acquire(int arg) {
     
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

acquireQueued方法

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

parkAndCheckInterrupt方法

    private final boolean parkAndCheckInterrupt() {
     
        LockSupport.park(this);
        return Thread.interrupted();
    }

如果interrupted 返回真,就会返回到acquire方法,进入if块内容。

    public final void acquire(int arg) {
     
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    static void selfInterrupt() {
     
    	//重新产生一次中断
        Thread.currentThread().interrupt();
    }

可打断模式

static final class NonfairSync extends Sync {
     
    public final void acquireInterruptibly(int arg)
            throws InterruptedException {
     
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);
    }

doAcquireInterruptibly方法

    private void doAcquireInterruptibly(int arg)
        throws InterruptedException {
     
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
     
            for (;;) {
     
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
     
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    //在park过程中如果被interrupt会进入此
                    //这时候抛出异常,而不会再次进入for(;;)
                    throw new InterruptedException();
            }
        } finally {
     
            if (failed)
                cancelAcquire(node);
        }
    }

你可能感兴趣的:(java,多线程,java)