Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐

目录

JDK中提供了哪些并发容器?

谈谈对BlockingQueue的理解?

谈谈你对ConcurrentHashMap的理解? 

谈谈对ConcurrentSkipListMap的理解?

谈谈对CopyOnWriteArrayList 的理解?

谈谈对Fork/Join架的理解?

谈谈对信号量semaphore的理解?

谈谈对ReentrantReadWriteLock 的理解?

谈谈对ReetrantLock的理解?


少年不惧岁月长,彼方尚有光荣在

 话不多说,发车!

JDK中提供了哪些并发容器?

  • ConcurrentHashMap:线程安全的hashmap
  • ConcurrentSkipListMap:跳表的实现类,使用跳表的数据结构进行快速查找
  • BlockingQueue:是一个接口,表示阻塞队列

Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第1张图片

实现类:

Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第2张图片

谈谈对BlockingQueue的理解?

  • 阻塞队列:当队列满时,队列会阻塞插入元素的线程,直到队列不满;当队列空时,队列会阻塞获取元素的线程,直到队列不为空
  • 经常用于生产者-消费者的场景:生产者是向队列中插入元素的线程,消费者是从队列里获取元素的线程

谈谈你对ConcurrentHashMap的理解? 

  •  hashmap线程不安全;hashtable效率低下,使用synchronized来保证线程安全,当一个线程访问hashtable的同步方法,其他线程也访问同步方法时,就会进入阻塞或者轮询状态
  • concurrenthashmap使用了锁分段技术,容器里有多把锁,每一把锁只锁一部分数据,那么当多线程访问容器里不同数据时,线程间就不存在竞争,可以提高并发访问的效率
  • concurrenthashmap是由segment和hashentry组成的,segment是一种可重入锁,hashentry用于存储键值对数据

谈谈对ConcurrentSkipListMap的理解?

是一种类似于链表的数据结构,基于二分的思想,其插入、删除、查询的时间复杂度都是O(logn);由很多层组成,每一层都是一个有序的链表,最底层的链表包含所有元素;对于每一层的任意一个节点,不仅指向下一个节点,还指向下一层;是一种用空间换时间的思想

Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第3张图片

谈谈对CopyOnWriteArrayList 的理解?

是一个线程安全的list,底层是一个数组;

它允许多个线程同时访问list中的数据,因为读取操作是安全的;如果要对数组进行操作,则需要先加锁,然后从原数组中拷贝出新数组,在新数组上进行操作之后再赋值给原数组,最后进行解锁;它利用了锁、数组拷贝保证了线程安全 

    /**
     * {@inheritDoc}
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        return get(getArray(), index);
    }
    @SuppressWarnings("unchecked")
    private E get(Object[] a, int index) {
        return (E) a[index];
    }
/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
    /**
     * {@inheritDoc}
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        return get(getArray(), index);
    }

谈谈对Fork/Join架的理解?

是一个用于并行执行任务的框架,它采用分而治之的思想,把一个大任务分成若干个小任务,最后把每个小任务的结果汇总起来形成大任务的结果;支持任务窃取机制,当有的线程完成任务时,会从双端任务队列的尾部获取任务来执行

谈谈对信号量semaphore的理解?

可以指定多个线程同时访问某个资源,线程先使用`semaphore`的acquire方法获取一个许可证,使用完之后再调用release方法来释放许可证,还可以用tryacquire来尝试获取许可证;semaphore主要用于流量控制的场景

    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    public void acquire(int permits) throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireSharedInterruptibly(permits);
    }
    //获取多个许可证
    public void release() {
        sync.releaseShared(1);
    }
    public boolean tryAcquire() {
        return sync.nonfairTryAcquireShared(1) >= 0;
    }

谈谈对ReentrantReadWriteLock 的理解?

基于AQS实现,是一个读写锁,支持重进入,它维护了一对锁,读锁和写锁:读锁可以被多个线程同时获取,而写锁一旦被获取,则其他读写线程都会被阻塞;它支持锁降级,即先把持住写锁,再获取到读锁,随后释放写锁,这样写锁就降级为读锁 

Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第4张图片

谈谈对ReetrantLock的理解?

ReentrantLock实现了Lock接口

Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第5张图片

`ReentrantLock`默认是使用非公平策略,如果想指定模式,可以通过入参fair来选择 

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

在ReentrantLock中,它用state来表示锁的状态,state状态值为0表示当前没有被任何线程持有,state状态值为1表示被其他线程持有,因为支持可重入,如果是持有锁的线程,再次获取同一把锁,直接成功,并且state状态值加1,线程释放锁state状态值减1,重入多次锁的线程,需要释放相应的次数。


Java实习生------JUC并发编程面试题(ConcurrentHashMap、BlockingQueue、ReetrantLock、semaphore)附源码解析⭐⭐⭐_第6张图片
整理面经不易,如果觉得有帮助的小伙伴点个赞吧~

 

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