1、volatile的原理
2、谈一下面向对象的"六原则一法则"。
3、ThreadLocal
4、Java中有几种线程池?
5、 Java多线程回调函数原理
1、volatile的原理
防止指令重排;保证一致性
内存屏障
1.阻止屏障两侧的指令重排序;
2.强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效。
2、谈一下面向对象的"六原则一法则"。
(一)单一职责原则:一个类只做它该做的事情。
(二)开闭原则:软件实体应当对扩展开放,对修改关闭。
(三)依赖倒转原则:面向接口编程。
该原则说的直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所代替。
(四)里氏替换原则:任何时候都可以用子类替换掉父类型。
(五)接口隔离原则:接口要小而专,绝不能大而全。
(六)合成聚合复用原则:优先使用聚合或合成关系复用代码。
(七)迪米特法则:它又称为最少知识原则,一个对象应当对其他对象有尽可能少的了解。
3、ThreadLocal
Thread中ThreadLocalMap作为成员变量;
ThreadLocalMap中以ThreadLocal为key,其对应的值为value。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);//通过当前线程获取ThreadLocalMap
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
10、Java中有几种线程池?
(1) newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
(2) newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
(3) newScheduledThreadPool创建一个定长线程池,支持定时和周期性任务执行(DelayedWorkQueue)
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
E first = q.peek();
if (first == null) {
if (nanos <= 0)
return null;
else
nanos = available.awaitNanos(nanos);
} else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
if (delay > 0) {
if (nanos <= 0)
return null;
if (delay > nanos)
delay = nanos;
long timeLeft = available.awaitNanos(delay);
nanos -= delay - timeLeft;
} else {
E x = q.poll();
assert x != null;
if (q.size() != 0)
available.signalAll();
return x;
}
}
}
} finally {
lock.unlock();
}
}
(4) newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Java多线程回调函数原理
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消boolean cancel(boolean mayInterruptIfRunning);、查询是否完成boolean isDone();、获取结果get()。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
类似AQS中的ConditionObject;WaitNode单向队列。
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos);
}
else
LockSupport.park(this);
}
}