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