Java併發編程--6.Exchanger線程間交換數據

在兩個線程之間定義同步點,當兩個線程都到達同步點時,他們交換數據結構,所以第一個線程的數據結構進入到第二個線程中,第二個線程的數據結構進入到第一個線程中數據結構

在生產者-消費者情境模式中它包含了一個數緩衝區,一個或者多個生產者,一個或者多個消費中ide

 

下面是生產者和消費者的示例:this

/**
 * 生產者和消費者交換數據
 */
public class MyExchanger {
    public static void main(String[] args) {
        Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
        
        Producer1 producer = new Producer1(new ArrayList<String>(), exchanger);
        Consumer1 consumer = new Consumer1(new ArrayList<String>(), exchanger);
        
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

/** 生產者線程*/
 class Producer1 implements Runnable{
    
    /**
     * 存儲交換的數據
     */
    private List<String> buffer;
    
    /**
     * 和消費者要交換的對象
     */
    private final Exchanger<List<String>> exchanger;
    
    Producer1(List<String> buffer,Exchanger<List<String>> exchanger){
        this.buffer = buffer;
        this.exchanger = exchanger;
    }
    
    @Override
    public void run() {
        for(int i = 0 ; i < 2 ; i++){
                String message = "" + i ;
                System.out.println("Produce的數據 : " + message);
                buffer.add(message);
            
            //調用exchange()與消費者進行數據交換
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        System.out.println("Produce收到來自Consumer的數據的長度 : " + buffer.size());
    }
}
 
/** 消費者線程*/ 
class Consumer1 implements Runnable{
        private List<String> buffer;
        
        private final Exchanger<List<String>> exchanger;
        
        public Consumer1(List<String> buffer,Exchanger<List<String>> exchanger){
            this.buffer = buffer;
            this.exchanger = exchanger;
        }
        
        @Override
        public void run() {
            for(int i = 0 ; i < 2 ; i++){
                //調用exchange()與消費者進行數據交換
                try {
                    buffer = exchanger.exchange(buffer);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                for(int j = 0 ; j < buffer.size() ; j++){
                    System.out.println("Consumer收到來自Produce的數據 : " + buffer.get(0));
                    buffer.remove(0);
                }
            }
            
            System.out.println("Consumer清空數據");
        }
    }

控制檯輸出:spa

Produce的數據 : 0
Consumer收到來自Produce的數據 : 0
Produce的數據 : 1
Produce收到來自Consumer的數據的長度 : 0
Consumer收到來自Produce的數據 : 1
Consumer清空數據

在Exchanger中,若是一個線程已經到達了exchanger節點時,對於它的夥伴節點的狀況有三種:線程

一、若是它的夥伴節點在該線程到達之間已經調用了exchanger方法,則它會喚醒它的夥伴而後進行數據交換,獲得各自數據返回。code

二、若是它的夥伴節點尚未到達交換點,則該線程將會被掛起,等待它的夥伴節點到達被喚醒,完成數據交換。對象

三、若是當前線程被中斷了則拋出異常,或者等待超時了,則拋出超時異常blog

相關文章
相關標籤/搜索