1.串流:Java將輸入/輸出抽象化爲串流,數據有來源及目的地,銜接二者的是串流對象。html
2.將數據歷來源取出,可使用輸入串流,表明對象爲java.io.Inputstream實例;將數據寫入目的地,可使用輸出串流,表明對象爲java.io.OutputStream實例。java
3.將數據歷來源取出,可使用輸入串流,表明對象爲java.io.Inputstream實例;將數據寫入目的地,可使用輸出串流,表明對象爲java.io.OutputStream實例。git
4.在不使用InputStream與OutputStream時,必須使用close()方法關閉串流。數組
1.標準輸入/輸出安全
~System.in~:標準輸入,文本模式下一般取得整行用戶輸入。可使用System的setIn()方法指定InputStream實例,從新指定標準輸入來源。多線程
~System.out~:標準輸出,能夠從新導向至文檔,只要執行程序時使用>將輸出結果導向至指定文檔,使用>>是附加信息。可使用System的setOut()方法指定printStream實例,將結果輸出至指定的目的地。架構
~System.err~:標準錯誤輸出串流,當即顯示錯誤信息。沒法從新導向。框架
2.FileInputStream與FileOutPutStream學習
~FileInputStream~是InputStream的子類,用於銜接文檔以讀入數據。指定文件名建立實例,一旦建立文檔就開啓,接着就可用來讀取數據。.net
~FileOutPutStream~是OutputStream的子類,用於銜接文檔以寫入數據。指定文件名建立實例,一旦建立文檔就開啓,接着就能夠用來寫出數據。
不管~FileInputStream~仍是~FileOutputStream~,不使用時都要使用close()關閉文檔。
1.BufferedOutputStream與BufferedInputStream:具有緩衝區做用,能夠默認或自定義緩衝區大小。
2.DataInputStream與DataOutputStream:具有數據轉換處理功能,自動在指定的類型與字節間轉換。
import java.io.IOException; import static java.lang.System.out; public class MemberDemo { public static void main(String[] args) throws IOException { Member[] members = { new Member("B1234", "Justin", 90), new Member("B5678", "Monica", 95), new Member("B9876", "Irene", 88) }; for(Member member : members) { member.save(); } out.println(Member.load("B1234")); out.println(Member.load("B5678")); out.println(Member.load("B9876")); } }
3.ObjectInputStream與ObjectOutputStream:具有對象串行化能力。
import static java.lang.System.out; public class Member2Demo { public static void main(String[] args) throws Exception { Member2[] members = {new Member2("B1234", "Justin", 90), new Member2("B5678", "Monica", 95), new Member2("B9876", "Irene", 88)}; for(Member2 member : members) { member.save(); } out.println(Member2.load("B1234")); out.println(Member2.load("B5678")); out.println(Member2.load("B9876")); } }
- synchronized與volatile
1.不具有線程安全的類:線程存取同一對象相同資源時可能引發競速狀況的類。
2.使用synchronized
每一個對象都會有個內部鎖定,或稱爲監控鎖定。被標示爲synchronized的區塊將會被監控,任何線程要執行synchronize區塊都必須先取得指定的對象鎖定。
線程沒法取得鎖定時會形成阻斷,不正確地使用synchronize有可能形成效能低下,另外一個問題則是死結。
synchronized要求達到的所標示區域的互斥性和可見性。互斥性是指synchronized區塊同時間只能有一個線程;可見性是指線程離開synchronized區塊後,另外一線程接觸到的就是上一線程改變後的對象狀態。
3.使用volatile
在變量上聲明volatile,標示變量是不穩定、易變的,也就是可能在多線程下存取。被標示爲volatile的變量,不容許線程快取,變量值的存取必定是在共享內存中進行。
volatile保證的是單一變數的可見性,線程對變量的存取必定是在共享內存中,不會在本身的內存空間中快取變量,線程對共享內存中變量的存取,另外一線程必定看獲得。
class Variable1 { static int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.printf("i = %d, j = %d%n", i, j); } } public class Variable1Test { public static void main(String[] args) { Thread thread1 = new Thread(() -> { while (true) { Variable1.one(); } }); Thread thread2 = new Thread(() -> { while (true) { Variable1.two(); } }); thread1.start(); thread2.start(); } }
1.調用鎖定對象的wait()方法:線程會釋放對象鎖定,並進入對象等待集合而處於阻斷狀態,其餘線程能夠競爭對象鎖定,取得鎖定的線程能夠執行synchronize區塊的代碼。
2.調用鎖定對象的notify()方法:從對象等待集合中隨機通知一個線程加入排班,再次執行synchronize前,被通知的其餘線程共同競爭對象鎖定。
3.調用鎖定對象的notifyAll()方法:全部等待集合中的線程都會被通知參與排班,這些線程會與其餘線程共同競爭對象鎖定。
1.使用Lock
lock接口主要操做類之一爲ReentrantLock,若是已經有線程取得Lock對象鎖定,嘗試在一次鎖定同一Lock對象是能夠的。
Lock接口還定義了tryLock()方法,若是線程調用tryLock()能夠取得鎖定會返回true,若沒法取得鎖定並不會發生阻斷,而是返回false。
2.ReadWriteLock
ReadWriteLock接口定義了讀取鎖定與寫入鎖定行爲,ReentrantReadWriteLock是ReadWriteLock接口的主要操做類,readLock()方法會返回ReentrantReadWriteLock.ReadLock實例,writeLock()犯法會返回ReentrantReadWriteLock.WriteLock實例。
3.使用StampedLock
支持樂觀讀取操做。在讀取線程不少,寫入線程不多的狀況下,程序能夠查看數據讀取以後是否遭到寫入線程的變動,再採起後續的措施。
4.使用Condition
Condition接口用來搭配Lock,Condition的await()、signal()、signalAll()方法,可視爲Object的wait()、notify()、notifyAll()方法的對應。
1.使用ThreadPoolExecutor:線程池這類服務的行爲其實是定義在Executor的子接口java.util.concurrent.ExecutorService中,一般會使用java.util.concurrent.Executor的newCacheThreadPool()、newFixedThreadPool()靜態方法來建立ThreadPoolExecutor實例,程序看起來較爲清楚且方便。
2.使用ScheduledThreadPoolExecutor:ScheduledExecutorService爲ExecutorService的子接口,可讓你進行工做排程。schedule()方法用來排定Runnable或Callable實例延遲多久後執行一次,並返回Future子接口ScheduledFuture的實例,對於重複性的執行,可以使用scheduleWithFixedDelay()和scheduleAtFixedRate()方法。
3.使用ForkJoinPool:ForkJoinPool閒聊了工做竊取演算,其創建的線程若是完成手邊任務,會嘗試尋找並執行其餘任務創建的資額任務,讓線程保持忙碌狀態,有效利用處理器的能力。ForkJoin框架適用於計算密集式的任務,較不適合用於容易形成線程阻斷的場合。
1.CopyOnWriteArrayList操做了List接口,這個類的實例在寫入操做時,內部會創建新數組,並複製原有數組索引的參考,而後在新數組上進行寫入操做,寫入完成後,再將內部原參考舊數組的變量參考至新數組。
2.CopyOnWriteArraySet操做了Set接口,內部特性與CopyOnWriteArrayList類似。
3.BlockedQueue是Queue的子接口,新定義了put()、take()方法。
4.ConcurrentMap是Map的子接口,其定義了putIfAbsent()、remove()、replace()等方法。這些方法都是原子操做。
5.ConcurrentHashMap是ConcurrentMap的操做類,ConcurrentNavigableMap是ConcurrentMap的子接口,其操做類爲ConcurrentSkipListMap,可視爲支持並行操做的TreeMap版本。
import java.util.concurrent.*; public class ProducerConsumerDemo3 { public static void main(String[] args) { BlockingQueue queue = new ArrayBlockingQueue(1); // 容量爲1 new Thread(new Producer3(queue)).start(); new Thread(new Consumer3(queue)).start(); } }
20155332盛照宗
這周利用了更多的課餘時間來寫代碼,發現了能夠更多的使用空閒時間來學習。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一週 | 10/10 | 1/1 | 10/10 | |
第二週 | 110/150 | 1/1 | 10/10 | |
第三週 | 150/150 | 1/1 | 10/10 | |
第四周 | 400/500 | 1/1 | 15/20 | |
第五週 | 430/500 | 1/1 | 20/30 | |
第六週 | 700/500 | 1/1 | 20/30 |
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。
計劃學習時間:XX小時
實際學習時間:XX小時
改進狀況:
(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表)