0907

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);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章