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