Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
832 views
in Technique[技术] by (71.8m points)

关于多线程中,线程获取的究竟是谁的锁

    public class Sample {
        Lock lock = new ReentrantLock();
        public void first() { // 当前线程连续持有 10 秒 sample 实例的锁
            try {
                lock.lock();
                for (int i = 0; i < 10; i++) {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
        public void second() { // 当前线程在启动后的 5 秒内不断尝试获取 sample 实例的锁
            boolean locked = false;
            try {
                locked = lock.tryLock(5, TimeUnit.SECONDS); // 参数 1:最长等待时间、参数 2:时间单位
                System.out.println(locked);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (locked) {
                    lock.unlock();
                }
            }
        }
    }
public class Solution {
    public static void main(String[] args) throws InterruptedException {
        Sample sample = new Sample();
        new Thread(sample::first).start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(sample::second).start();
    }
}

请教示例代码中,两个线程在竞争锁,但线程竞争的是 sample 对象的锁,还是 lock 对象的锁呢?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

1、ReentrantLock 中存在名为 Sync 的内部类
2、Sync 为 AbstractQueuedSynchronizer(AQS)的子类
3、AQS 中存在名为 state 的成员变量
4、可重入锁加锁的过程就是通过 CAS 将 AQS 中的成员变量 state 由 0 变 1 的过程
5、程序前 10 秒 fisrt 线程已将 state 由 0 变 1,第 10 秒才将 1 恢复为 0
6、因此 second 线程在第 5 秒调用 tryLock 发现 state 为 1 则已经获取锁失败


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...