Java併發
(Executor框架和多線程基礎)
Thread與Runable如何實現多線程
Java 5以前實現多線程有兩種實現方法:一種是繼承Thread類;另一種是實現Runnable接口。兩種方式都要通過重寫run()方法來定義線程的行爲,推薦使用後者,因爲Java中的繼承是單繼承,一個類有一個父類,如果繼承了Thread類就無法再繼承其他類了,顯然使用Runnable接口更爲靈活。
實現Runnable接口相比繼承Thread類有如下優勢:
- 可以避免由於Java的單繼承特性而帶來的侷限
- 增強程序的健壯性,代碼能夠被多個程序共享,代碼與數據是獨立的
- 適合多個相同程序代碼的線程區處理同一資源的情況
補充:Java 5以後創建線程還有第三種方式:實現Callable接口,該接口中的call方法可以在線程執行結束時產生一個返回值,代碼如下所示:
class MyTask implements Callable<Integer> {
private int upperBounds;
public MyTask(int upperBounds) {
this.upperBounds = upperBounds;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i = 1; i <= upperBounds; i++) {
sum += i;
}
return sum;
}
}
public class Test {
public static void main(String[] args) throws Exception {
List<Future<Integer>> list = new ArrayList<>();
ExecutorService service = Executors.newFixedThreadPool(10);
for(int i = 0; i < 10; i++) {
list.add(service.submit(new MyTask((int) (Math.random() * 100))));
}
int sum = 0;
for(Future<Integer> future : list) {
while(!future.isDone()) ;
sum += future.get();
}
System.out.println(sum);
}
}
線程同步的方法有什麼;鎖,synchronized塊,信號量等
鎖的等級:方法鎖、對象鎖、類鎖
生產者消費者模式的幾種實現,阻塞隊列實現,sync關鍵字實現,lock實現,reentrantLock等
ThreadLocal的設計理念與作用,ThreadPool用法與優勢(這裏在Android SDK原生的AsyncTask底層也有使用)
線程池的底層實現和工作原理(建議寫一個雛形簡版源碼實現)
幾個重要的線程api,interrupt,wait,sleep,stop等等
寫出生產者消費者模式。
ThreadPool用法與優勢。
Concurrent包裏的其他東西:ArrayBlockingQueue、CountDownLatch等等。
wait()和sleep()的區別。
sleep()方法是線程類(Thread)的靜態方法,導致此線程暫停執行指定時間,將執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復(線程回到就緒(ready)狀態),因爲調用sleep 不會釋放對象鎖。wait()是Object 類的方法,對此對象調用wait()方法導致本線程放棄對象鎖(線程暫停執行),進入等待此對象的等待鎖定池,只有針對此對象發出notify 方法(或notifyAll)後本線程才進入對象鎖定池準備獲得對象鎖進入就緒狀態。
3、IO(IO,NIO,目前okio已經被集成Android包)
IO框架主要用到什麼設計模式
JDK的I/O包中就主要使用到了兩種設計模式:Adatper模式和Decorator模式。
NIO包有哪些結構?分別起到的作用?
NIO針對什麼情景會比IO有更好的優化?
OKIO底層實現