1.对Java三大特性的理解?
2.封装的好处是什么?
3.可以在static环境中调用非static变量吗?
4.HashMap
5.ConcurrentHashMap和synchronizedMap()转换的Map有什么不同?
ConcurrentHashMap是分开锁定每个链表的头结点,因此允许多个线程在ConcurrentHashMap中操作不同位置的数据。
而synchronizedMap()是锁定整个Map集合,同一时间只允许一个线程操作整个Map。
6.为什么线程放回线程池以后不会被销毁?
1)因为线程池在判断任务是否为空时,执行的是一个永远为真的循环,保证线程不断的运行。
runWorker方法中:while (task != null || (task = getTask()) != null) {}
2)线程执行完后,会继续执行getTask获取任务的逻辑,
getTask方法中:Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
timed是判断当前线程是否为非核心线程,如果是核心线程,那么会调用 workQueue.take() 一直保持阻塞状态直到获取任务为止。
如果当前线程不是核心线程,那么久会调用poll()方法等待一定时间,如果等待超时,那么就会回收该线程。
3)通过这两个死循环来保证核心线程不会被销毁,并且能够不断的接收任务来执行。
有关方法、注解:
ThreadPoolExecutor中的runWorker和getTask方法。
workQueue.take()方法的注解:
意思是take方法会在必要时一直等待直到元素可以用,也就是能够获取到元素。
/**
* Retrieves and removes the head of this queue, waiting if necessary
* until an element becomes available.
*
* @return the head of this queue
* @throws InterruptedException if interrupted while waiting
*/
E take() throws InterruptedException;
线程池的底层原理:
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
7.像王者荣耀这样的游戏用到了什么协议?
udp协议,及时更新状态比保持状态信息完整更重要。