讓兩個線程安全的交換對象

JDK中有一個Exchanger交換類可讓兩個線程的對象安全互換,注意這裏是互換,而不是誰傳給誰。這是一個傳遞字符數組的互換。數組

public class ProducerTask implements Runnable {
    private final Exchanger<char[]> exchanger;
    private char[] buffer = null;
    private char index = 0;
    private final Random random;
    public ProducerTask(Exchanger<char[]> exchanger,char[] buffer,long seed) {
        this.exchanger = exchanger;
        this.buffer = buffer;
        this.random = new Random(seed);
    }
    @Override
    public void run() {
        try {
//            while (true) {
            //向緩衝區填充字符
            for (int i = 0; i < buffer.length; i++) {
                buffer[i] = nextChar();
                System.out.println(Thread.currentThread().getName() + ": " + buffer[i] + " -> ");
            }
            //交換緩衝區
            System.out.println(Thread.currentThread().getName() + ": BEFORE exchange");
            //此處會將使用同一個交換機的兩個線程的字符數組互換,若是一個字節數組爲空,次數爲堵塞等待
            buffer = exchanger.exchange(buffer);
            System.out.println(Thread.currentThread().getName() + ": AFTER exchange");
            for (int i = 0;i < buffer.length;i++) {
                System.out.println(Thread.currentThread().getName() + ": -> " + buffer[i]);
            }
//            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private char nextChar() throws InterruptedException {
        char c = (char)('A' + index % 26);
        index++;
//        Thread.sleep(random.nextInt(1000));
        return c;
    }
}
public class SteadTask implements Runnable {
    private final Exchanger<char[]> exchanger;
    private char[] buffer = null;
    private final Random random;
    private char index = 0;

    public SteadTask(Exchanger<char[]> exchanger, char[] buffer,long seed) {
        this.exchanger = exchanger;
        this.buffer = buffer;
        this.random = new Random(seed);
    }

    @Override
    public void run() {
        try {
//            while (true) {
            //向緩衝區填充字符
            for (int i = 0; i < buffer.length; i++) {
                buffer[i] = nextChar();
                System.out.println(Thread.currentThread().getName() + ": " + buffer[i] + " -> ");
            }
            //交換緩衝區
            System.out.println(Thread.currentThread().getName() + ": BEFORE exchange");
            //此處會將使用同一個交換機的兩個線程的字符數組互換
            buffer = exchanger.exchange(buffer);
            System.out.println(Thread.currentThread().getName() + ": AFTER exchange");
            for (int i = 0;i < buffer.length;i++) {
                System.out.println(Thread.currentThread().getName() + ": -> " + buffer[i]);
            }
//            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private char nextChar() throws InterruptedException {
        char c = (char)('Z' - index % 26);
        index++;
//        Thread.sleep(random.nextInt(1000));
        return c;
    }
}
public class Main {
    public static void main(String[] args) {
        Exchanger<char[]> exchanger = new Exchanger<>();
        char[] buffer1 = new char[10];
        char[] buffer2 = new char[10];
        new Thread(new ProducerTask(exchanger,buffer1,314159)).start();
//        new Thread(new ConsumerTask(exchanger,buffer2,265358)).start();
        new Thread(new SteadTask(exchanger,buffer2,265358)).start();
    }
}

運行結果:安全

Thread-1: Z -> 
Thread-0: A -> 
Thread-1: Y -> 
Thread-0: B -> 
Thread-1: X -> 
Thread-0: C -> 
Thread-1: W -> 
Thread-0: D -> 
Thread-1: V -> 
Thread-0: E -> 
Thread-1: U -> 
Thread-0: F -> 
Thread-1: T -> 
Thread-0: G -> 
Thread-0: H -> 
Thread-0: I -> 
Thread-0: J -> 
Thread-1: S -> 
Thread-0: BEFORE exchange
Thread-1: R -> 
Thread-1: Q -> 
Thread-1: BEFORE exchange
Thread-1: AFTER exchange
Thread-1: -> A
Thread-1: -> B
Thread-1: -> C
Thread-1: -> D
Thread-1: -> E
Thread-0: AFTER exchange
Thread-1: -> F
Thread-1: -> G
Thread-1: -> H
Thread-1: -> I
Thread-1: -> J
Thread-0: -> Z
Thread-0: -> Y
Thread-0: -> X
Thread-0: -> W
Thread-0: -> V
Thread-0: -> U
Thread-0: -> T
Thread-0: -> S
Thread-0: -> R
Thread-0: -> Qdom

相關文章
相關標籤/搜索