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);
}
}