20155324 2016-2017-2 《Java程序設計》第6周學習總結

20155324 2016-2017-2 《Java程序設計》第6周學習總結

教材學習內容總結

InputStream與OutputStream

  • 串流設計

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()方法:全部等待集合中的線程都會被通知參與排班,這些線程會與其餘線程共同競爭對象鎖定。

Lock、ReadWriteLock與Condition

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()方法的對應。

使用Executor

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框架適用於計算密集式的任務,較不適合用於容易形成線程阻斷的場合。

並行Collection簡介

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

教材學習中的問題和解決過程

  • 問題1:p305, IO.java: ~InputStream/OutputStream~的使用?
  • 問題1解決方案:串流設計、intputstream、outputstream的理解,經過對書上代碼的理解明白了。

代碼調試中的問題和解決過程

  • 問題1:git commit的時候不能成功
  • 問題1解決方案:後來從新初始化.git庫就好了

代碼託管

上週考試錯題總結

  • StandardOut.java 輸出"HelloWorld"到hello.txt內容的java命令是(java cc.openhome.StandardOut hello.txt)
  • 對書本上的課本記得不夠牢固,後經過翻閱書籍等知道了錯誤
  • 錯題2及緣由,理解狀況
  • ...

結對及互評

20155332盛照宗

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20155332
    • 結對照片
    • 結對學習內容
      • 我向他詢問了關於調用鎖定對象的wait()方法的知識點,理解更加深入了。
      • 一塊兒寫代碼。並解決問題
      • ...
  • 上週博客互評狀況

其餘(感悟、思考等,可選)

這周利用了更多的課餘時間來寫代碼,發現了能夠更多的使用空閒時間來學習。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 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小時

  • 改進狀況:

(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表
)

參考資料

相關文章
相關標籤/搜索