LockSupport,高频面试题,AQS源码,以及源码阅读方法论

LockSupport

  • 锁支持
public class LockSupportTest {
    LockSupport.park();
    LockSupport.unpark(t);
}
1
2
3
4

面试题

题目1

实现一个容器,提供两个方法,add,size,写两个线程,
线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束


















 

 














 





 













public class Problem1 {

    private static final int TOTAL_SIZE = 10;
    private static final int OUT_SIZE = 5;
    private List<Object> lists = new ArrayList<>(TOTAL_SIZE);

    public static void main(String[] args) {
        Problem1 p = new Problem1();
        final Object lock = new Object();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("t1 begin...");
                for (int i = 0; i < TOTAL_SIZE; i++) {
                    p.add(i);
                    System.out.println("t1 add " + i);
                    if (p.size() == OUT_SIZE) {
                        lock.notify();
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                System.out.println("t1 end...");
            }
        }).start();

        new Thread(() -> {
            System.out.println("t2 begin...");
            synchronized (lock) {
                try {
                    if (p.size() != OUT_SIZE) {
                        lock.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2 end...");
                lock.notify();
            }
        }).start();
    }

    public void add(Object o) {
        lists.add(o);
    }

    public int size() {
        return lists.size();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

题目2

写一个固定容量同步容器,拥有put和get方法,以及getCount方法,
能够支持2个生产者线程以及10个消费者线程的阻塞调用

public class Problem2<T> {
    private final LinkedList<T> lists = new LinkedList<>();
    private final int MAX = 10;
    private int count = 0;

    private Lock lock = new ReentrantLock();
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {
        Problem2<String> p = new Problem2<>();
        //启动消费者线程
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 5; j++) {
                    System.out.println(p.get());
                }
            }, "consumer" + i).start();
        }
        TimeUnit.SECONDS.sleep(2);
        //启动生产者线程
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                for (int j = 0; j < 25; j++) {
                    p.put(Thread.currentThread().getName() + " " + j);
                }
            }, "producer" + i).start();
        }
    }

    public void put(T t) {
        try {
            lock.lock();
            while (lists.size() == MAX) { //想想为什么用while而不是用if?
                producer.await();
            }
            lists.add(t);
            ++count;
            consumer.signalAll(); //通知消费者线程进行消费
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T get() {
        T t = null;
        try {
            lock.lock();
            while (lists.size() == 0) {
                consumer.await();
            }
            t = lists.removeFirst();
            count--;
            producer.signalAll(); //通知生产者进行生产
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return t;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

AQS(CLH(三个人首字母缩写))

核心
volatile state 根据子类不同实现,意义不同
Node 双向链表 节点装的是Thread,监控上面的state

public abstract class AbstractQueuedSynchronizer{
    private volatile int state;

    static final class Node {
        volatile Node prev;
        volatile Node next;
        volatile Thread thread;
    }
}
1
2
3
4
5
6
7
8
9
  • ReentrantLock state 0、1、2... 代表 解锁、加锁、锁重入...
  • CountDownLatch
总字数: 647 字  上次更新: 2023-03-14 00:25:11