美文网首页
Android面试Java基础篇(二)

Android面试Java基础篇(二)

作者: 肖义熙 | 来源:发表于2021-03-22 14:04 被阅读0次

    (一)问:Java线程池的实现原理和使用

    线程池即存放和管理线程的一个池子

    (1)复用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。

    (2)能够有效的控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。

    (3)能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能。

    当向线程池提交任务时:

    (1)线程池判断核心线程池里的线程是否都在执行任务(核心线程池是不是已经满载状态)。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。

    (2)线程池判断工作队列是否已经满(有界队列)。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。

    (3)线程池判断线程池的线程(临时线程)是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务(抛出异常、交给提交任务的线程、等待线程、剃除第一个线程加入等等)

    线程池构造函数:

    ThreadPoolExecutor(int corePoolSize,  int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runable> workQueue, ThreadFactory threadFactory, RejectedExcutionHandler handler)

    corePoolSize:核心线程数

    maximumPoolSize: 总线程数

    keepAliveTime:线程超时时间,设置超时时间,如果线程空闲则会被回收。 unit为超时时间的单位。

    workQueue:它是一个等待执行的任务队列(工作队列),如果核心线程没有空闲的了,新来的任务就会被放到这个等待队列中

    threadFactory:线程工厂,用于生成临时线程

    handler:指定取舍策略,如果任何无法在核心线程、工作队列、临时线程中都得不到执行,则需要做取舍的。

    (二)问:线程同步有哪些方式

    答:使用多线程时,保证数据的唯一性和准确性,所以要使用线程同步,线程同步有以下五种方式:

        (1)synchronized关键字(对方法或代码块),如果方法是静态代码,会锁住整个类。通常只需要使用synchronized(this){} 代码块,一般不需要锁住整个方法或类

        (2)使用重入锁ReentrantLock(),需要手动lock() 和 unlock()

        (3)使用局部变量ThreadLocal,如果使用ThreadLocal管理变量,那么每一个使用该变量的线程都会获得该变量的副本,这样每一个线程可以随意修改自己的副本,不会对其他线程产生影响。

        (4)使用阻塞队列LinkedBlockingQueue<E e>,put(E e) 队列末尾添加元素,如果队列满则阻塞, take() 返回队首并移除,如果队空则阻塞。

        (5)使用特殊域变量(volatile)实现线程同步

    (三)问:什么是死锁?如何解决或预防产生死锁

    答:死锁,就是指两个或两个以上的线程/进程在执行的过程中,因争夺资源而造成的一种相互等到的现象。例如:线程A持有锁A, 线程B持有锁B,此时线程A请求获取锁B,线程B请求获取锁A,就造成了相互等待的结果,也就是死锁。

    解决方案:

        1.避免在同步代码块中调用外部的同步方法。

        2.在嵌套多层synchronized的代码块中,通过对象唯一值给对象锁进行排序,例如使用对象的hashCode值进行排序,使得每次获取锁的顺序是一致的。

    相关文章

      网友评论

          本文标题:Android面试Java基础篇(二)

          本文链接:https://www.haomeiwen.com/subject/znuzcltx.html