Java知识点学习(第10天)

Java死锁如何避免?

造成死锁的几个原因:

  1. 一个资源只能被一个线程使用。
  2. 一个线程在阻塞等待某个资源时,不会释放自己拥有的资源。
  3. 一个线程已经获得的资源,在未使用完之前,不能被强行剥夺。
  4. 若干线程形成收尾相接的循环等待资源关系。

这4个条件就是形成死锁必要的4个条件,想要避免死锁,只要不满足上面的一个条件即可,但是前三个条件是作为锁要符合的条件,所以只能去打破第四个条件,不出现循环等待锁的关系。

在开发过程中:

  1. 保证加锁的顺序,保证每个线程按照同样的顺序进行加锁。
  2. 注意加锁的时限,可以针对其设置加锁的时间。
  3. 注意死锁的检查,确保在第一时间发现死锁并进行解决。

线程池的底层工作原理

线程池本身是通过队列+线程实现的:

  1. 如果此时线程池中的线程数小于corePoolSize,即使线程池中的线程处于空闲状态,我们也需要创建新的线程来处理被添加的任务。
  2. 如果此时线程池中的线程数等于corePoolSize,但是缓冲队列workQueue没有满,那么任务会被放入缓存队列。
  3. 如果此时线程池中的线程数大于等于corePoolSize,且缓冲队列workQueue满了,并且线程池中的线程数量小于maximumPoolSize,建新等线程来处理被添加的任务。
  4. 如果此时线程池中的线程数大于corePoolSize,且缓冲队列workQueue满了,并且线程池中的线程数量等于maximumPoolSize,需要通过handler指定拒绝策略来处理此任务。
  5. 如果线程池中的线程数大于corePoolSize,如果某线程空闲时间超过了KeepAliveTime,线程将被终止,这样线程池能够动态调整线程池中的线程数量。

线程池为什么是先添加队列而不是先创建最大线程?

我们从上一题知道,当线程池的核心线程都在忙的时候,如果继续向线程池中添加任务,线程池会将任务放在缓冲队列中,等队列满了,再新开线程。就好比你是一家公司老板,手下有10个Java程序员,当有大量业务来的时候,你不会直接去找人,你会让这个10个程序员先做,做不完的任务放一边,做不完的任务堆不下了,你才会去招新的员工。

ReentrantLock中的tryLock()和lock()方法的区别

  1. tryLock()表示尝试加锁,可能加到锁,也可能加不到,该方法不会阻塞线程,如果加到锁就会返回true,反之返回false。
  2. lock()表示阻塞加锁,线程会阻塞直到加到锁,该方法没有返回值。

你可能感兴趣的:(Java知识点,java)