2.LinkedBlockingQueue:基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列,当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回、只有当队列缓冲区达到大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒。可以有多个线程进行同时操作。
  3.DelayQueue: DelayQueue里面放的是实现了Delayed的接口,Delayed接口需要实现两个方法:getDelay(TimeUnit unit)是为了返回该任务锁需延长的时间,compareTo(Delayed o)是为了比较到底那个任务需要排在前面,当使用queue.take()的时候延时开始,此时本线程挂起,直到延时结束开始运行run()中的任务。
  4.PriorityBlockingQueue: 基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定),但需要注意的是PriorityBlockingQueue并不会阻塞数据生产者,而只会在没有可消费的数据时,阻塞数据的消费者。因此使用的时候要特别注意,生产者生产数据的速度不能快于消费者消费数据的速度,否则时间一长,会终耗尽所有的可用堆内存空间。
  5.PriorityQueue:非线程安全的优先队列。
  17.列出几种线程池
  1.ThreadPoolExecutor:通过Executors可以构造单线程池、固定数目线程池、不固定数目线程池。
  2.ScheduledThreadPoolExecutor:可以延时调用线程或者延时重复调度线程。
  18.解释一下java内存模型
  1.每个线程有自己的共享变量副本(实例域、静态域、数组元素)
  2.Java线程之间的通讯由java内存模型控制(JMM),JMM决定了一个线程对共享变量的写入在什么时候对另一个线程可见。
  3.当一个A线程改变了一个共享变量,此时只是改变了自己本地共享变量的副本,所以线程之间要实现通讯需要先将A线程的本地副本,刷入到主存之中,然后线程B去主存中读取线程A刷入的改变的变量。
  19.解释一下java代码的原子性
  1.除了long和double,其他基本类型的简单操作都是原子性操作:读取、写入数字。
  2.java1.5之后使用volatile关键字能够让long和double像其他基本类型一样。
  3.不能因为有原子性,放弃同步。
  20.解释一下volatile字段
  1.在了解了java内存模型之后,我们知道volatile关键字保证了,某个共享变量改变之后,另一个线程中本地共享变量的副本也会立即刷新。
  2.当某个域的值依赖于它之前的值,如计数递增那么volatile会失效。
  3.使用volatile而不使用synchronized的情况是类中只有一个可变域,其他时候都应该使用synchronized。
  21.解释一下synchronized字段
  1.synchronized可以用于修饰方法,在某线程从某个用synchronized修饰的方法返回之前,其他所有要调用这个对象中任意使用synchronized修饰的方法的线程都会被阻塞。即同一时刻某个对象中只能有一个synchronized修饰的方法被调用。
  2.对于某个对象,其所有synchronized方法共享一把锁,也是说一个对象中含有一把锁(也叫监视器)。
  3.一个线程可以多次获取某个对象的锁,比如一个synchronized方法中调用了该对象中另一个synchronized方法。那么这个锁的计数会变成2,每从一个synchronized方法离开都会使计数减一,每进入一个synchronized方法都会使计数加一。
  4.每个类也有一把锁(属于类的Class的一部分),所以synchronized static可以防止类范围内对于static数据的并发访问。
  22.Lock的使用
  1.在lock()和unlock()之间我们可以创建一个临界资源,同时一时刻只能有一个线程访问这个资源。。
  2.我们可以对临界区域进行异常捕捉,注意return必须在try里面,防止过早释放临界资源。
  3.使用Lock的好处在于我们能处理某些异常,而使用synchronized我们无法对异常进行清理工作。
  23.wait()和sleep()区别
  1.该方法在Object中,可以将当前线程挂起,需要在synchronized控制的块中,因为wait需要获取需要挂起的线程所要处理对象的锁,否则会报错。在wait()中锁是被释放的。
  2.该方法是属于Thread类中、sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,线程不会释放对象锁。
  24.死锁产生的条件
  1.至少有一个资源是不能被共享的
  2.至少有一个任务持有一个资源并且在等待另一个资源
  3.资源不能被抢占
  4.必须有循环等待