让两个线程安全的交换对象 顶

2019-08-20 10:03:40 浏览数 (1)

JDK中有一个Exchanger交换类可以让两个线程的对象安全互换,注意这里是互换,而不是谁传给谁。这是一个传递字符数组的互换。

代码语言:javascript复制
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;
    }
}
代码语言:javascript复制
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;
    }
}
代码语言:javascript复制
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: -> Q

0 人点赞