Java併發編程中級篇(七):併發任務間交換數據

Java API提供了一個同步輔助類Exchanger。它容許你在線程執行過程當中在線程之間交換數據。它的機制是在線程中設置通步點,當兩個線程都到達同步點之時,它們交換數據結構,所以第一個線程的數據結構進入到第二個線程中,同時第二個線程的數據結構進入到第一個線程中。java

Exchange應用侷限於兩個線程,因此咱們能夠使用Exchange來模擬只有一個生產者和一個消費者的生產者-消費者問題。緩存

建立一個生產者線程類Producer,聲明一個List<String>做爲緩衝區,一個Exchange<List<String>>用來和消費者交換數據。線程的執行方法中,循環10次,每次向緩衝區中加入10個記錄並調用Exchange.exchange(),方法來和消費者交換數據。最後打印緩衝區記錄數和當前循環次數。數據結構

public class Producer implements Runnable {
    private List<String> buffer;
    private Exchanger<List<String>> exchanger;

    public Producer(List<String> buffer, Exchanger<List<String>> exchanger) {
        this.buffer = buffer;
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        int cycle = 1;
        for (int i = 0; i < 10; i++) {
            System.out.printf("Producer: Cycle %d\n", cycle);
            for (int j = 0; j < 10; j++) {
                String message = "Event" + (i * 10 + j);
                System.out.printf("Producer: %s\n", message);
                buffer.add(message);
            }
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("Producer: %d\n", buffer.size());
            cycle++;
        }
    }
}

建立一個消費者線程類,一樣聲明一個數據緩衝區List<String>和一個Exchange用於和生產者交換數據。執行10次循環,每次循環使用exchanger.exchange()方法等待和生產者交換數據,交換數據成功後打印數據緩衝區的內容。ide

public class Consumer implements Runnable{
    private List<String> buffer;
    private Exchanger<List<String>> exchanger;

    public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) {
        this.buffer = buffer;
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        int cycle = 1;
        for (int i = 0; i < 10; i++) {
            System.out.printf("Consumer: Cycle %d\n", cycle);
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("Consumer: Buffer size %d\n", buffer.size());
            for(Iterator<String> iterator = buffer.iterator(); iterator.hasNext();) {
                String message = iterator.next();
                System.out.printf("Consumer: %s\n", message);
                iterator.remove();
            }
            cycle++;
        }
    }
}

建立主方法類,聲明兩個List<Stting>分別做爲生產者和消費者的數據緩衝區,聲明一個Exchanger對象用於在生產者線程和消費者線程之間交換數據。而後啓動兩個線程。this

public class Main {
    public static void main(String[] args) {
        List<String> buffer1 = new ArrayList<String>();
        List<String> buffer2 = new ArrayList<String>();
        Exchanger<List<String>> exchanger = new Exchanger<List<String>>();

        Thread threadP = new Thread(new Producer(buffer1, exchanger));
        Thread threadC = new Thread(new Consumer(buffer2, exchanger));

        threadP.start();
        threadC.start();
    }
}

查看控制檯執行結果。執行開始後消費者線程持有一個空緩衝區,並等待和生產者線程在第一個同步點交換數據。生產者則向一個空的緩衝區中寫入10條記錄,而後再第一個同步點與消費者交換數據。在這個同步點上,消費者得到生產者的10條記錄的緩存,生產者得到消費者的空緩存,因此你會看到消費者打印緩存中的10條記錄,而生產者交換後的緩存數據量爲0.線程

Producer: Cycle 1
Producer: Event0
Producer: Event1
Producer: Event2
Producer: Event3
Producer: Event4
Producer: Event5
Producer: Event6
Producer: Event7
Producer: Event8
Producer: Event9
Consumer: Cycle 1
Producer: 0
Producer: Cycle 2
Producer: Event10
Producer: Event11
Producer: Event12
Producer: Event13
Producer: Event14
Producer: Event15
Producer: Event16
Producer: Event17
Producer: Event18
Producer: Event19
Consumer: Buffer size 10
Consumer: Event0
Consumer: Event1
Consumer: Event2
Consumer: Event3
Consumer: Event4
Consumer: Event5
Consumer: Event6
Consumer: Event7
Consumer: Event8
Consumer: Event9
Consumer: Cycle 2
Consumer: Buffer size 10
Consumer: Event10
Consumer: Event11
Consumer: Event12
Consumer: Event13
Consumer: Event14
Consumer: Event15
Consumer: Event16
Consumer: Event17
Consumer: Event18
Consumer: Event19
Consumer: Cycle 3
Producer: 0
Producer: Cycle 3
Producer: Event20
Producer: Event21
Producer: Event22
Producer: Event23
Producer: Event24
Producer: Event25
Producer: Event26
Producer: Event27
Producer: Event28
Producer: Event29
Producer: 0
Producer: Cycle 4
Producer: Event30
Producer: Event31
Consumer: Buffer size 10
Consumer: Event20
Producer: Event32
Consumer: Event21
Consumer: Event22
Consumer: Event23
Producer: Event33
Consumer: Event24
Consumer: Event25
Consumer: Event26
Consumer: Event27
Consumer: Event28
Consumer: Event29
Consumer: Cycle 4
Producer: Event34
Producer: Event35
Producer: Event36
Producer: Event37
Producer: Event38
Producer: Event39
Producer: 0
Producer: Cycle 5
Producer: Event40
Consumer: Buffer size 10
Consumer: Event30
Consumer: Event31
Consumer: Event32
Consumer: Event33
Producer: Event41
Producer: Event42
Consumer: Event34
Producer: Event43
Consumer: Event35
Producer: Event44
Consumer: Event36
Producer: Event45
Consumer: Event37
Consumer: Event38
Consumer: Event39
Consumer: Cycle 5
Producer: Event46
Producer: Event47
Producer: Event48
Producer: Event49
Producer: 0
Producer: Cycle 6
Consumer: Buffer size 10
Consumer: Event40
Consumer: Event41
Producer: Event50
Consumer: Event42
Consumer: Event43
Consumer: Event44
Producer: Event51
Consumer: Event45
Producer: Event52
Consumer: Event46
Producer: Event53
Consumer: Event47
Producer: Event54
Producer: Event55
Producer: Event56
Producer: Event57
Producer: Event58
Producer: Event59
Consumer: Event48
Consumer: Event49
Consumer: Cycle 6
Consumer: Buffer size 10
Consumer: Event50
Consumer: Event51
Consumer: Event52
Consumer: Event53
Consumer: Event54
Consumer: Event55
Consumer: Event56
Consumer: Event57
Consumer: Event58
Consumer: Event59
Consumer: Cycle 7
Producer: 0
Producer: Cycle 7
Producer: Event60
Producer: Event61
Producer: Event62
Producer: Event63
Producer: Event64
Producer: Event65
Producer: Event66
Producer: Event67
Producer: Event68
Producer: Event69
Producer: 0
Producer: Cycle 8
Producer: Event70
Producer: Event71
Producer: Event72
Producer: Event73
Producer: Event74
Producer: Event75
Producer: Event76
Producer: Event77
Producer: Event78
Producer: Event79
Consumer: Buffer size 10
Consumer: Event60
Consumer: Event61
Consumer: Event62
Consumer: Event63
Consumer: Event64
Consumer: Event65
Consumer: Event66
Consumer: Event67
Consumer: Event68
Consumer: Event69
Consumer: Cycle 8
Consumer: Buffer size 10
Producer: 0
Producer: Cycle 9
Consumer: Event70
Producer: Event80
Consumer: Event71
Consumer: Event72
Producer: Event81
Consumer: Event73
Producer: Event82
Consumer: Event74
Consumer: Event75
Consumer: Event76
Producer: Event83
Consumer: Event77
Producer: Event84
Producer: Event85
Consumer: Event78
Consumer: Event79
Consumer: Cycle 9
Producer: Event86
Producer: Event87
Producer: Event88
Producer: Event89
Producer: 0
Producer: Cycle 10
Consumer: Buffer size 10
Consumer: Event80
Producer: Event90
Producer: Event91
Consumer: Event81
Producer: Event92
Consumer: Event82
Producer: Event93
Consumer: Event83
Producer: Event94
Consumer: Event84
Consumer: Event85
Consumer: Event86
Consumer: Event87
Consumer: Event88
Producer: Event95
Producer: Event96
Producer: Event97
Producer: Event98
Consumer: Event89
Consumer: Cycle 10
Producer: Event99
Producer: 0
Consumer: Buffer size 10
Consumer: Event90
Consumer: Event91
Consumer: Event92
Consumer: Event93
Consumer: Event94
Consumer: Event95
Consumer: Event96
Consumer: Event97
Consumer: Event98
Consumer: Event99
相關文章
相關標籤/搜索