栅栏分两类
CyclicBarrier
干什么用的
线程到达栅栏的位置时调用await方法,该线程会被阻塞,直到所有线程都到达栅栏位置。
当所有线程都到达栅栏位置,那么栅栏将打开,此时所有线程都被释放,栅栏将被重置以便下次使用。
栗子
一家人去吃肯德基,当大家都到齐了进行点名,一起进入。
package test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Solver {
CyclicBarrier barrier;
class Worker implements Runnable {
private String name;
public Worker(String name) {
this.name = name;
}
public void run() {
try {
int await = barrier.await();
System.out.println("" + name + "第" + await + "个到达门口");
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
public void eatKFC(int numbers) throws InterruptedException {
Runnable barrierAction = new Runnable() {
public void run() {
System.out.println("都到齐了,看看谁先到的");
}
};
barrier = new CyclicBarrier(numbers, barrierAction);
new Thread(new Worker("你二叔")).start();
new Thread(new Worker("你大舅")).start();
new Thread(new Worker("你七大爷")).start();
new Thread(new Worker("你五叔")).start();
}
public static void main(String[] args) {
Solver solver = new Solver();
try {
solver.eatKFC(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Exchanger
干什么用的
栅栏的第二种形式
用于交换数据,A线程中的a数据,想和B线程中的b数据交换,当调用exchange时,会实现数据交换
栗子
一个班级的小A想和同一班级的小B换座位
package test;
import java.util.concurrent.Exchanger;
class FillAndEmpty {
Exchanger<Student> exchanger = new Exchanger<Student>();
Student student1 = new Student("xieyaoyan", 1);
Student student2 = new Student("yingyinglei", 2);
class FillingLoop implements Runnable {
public void run() {
try {
System.out.println(student1.getName() + " 收拾书包,走向另一个座位");
student1 = exchanger.exchange(student1);
System.out.println("换完座位了,当前座位是: " + student1);
} catch (InterruptedException ex) {
System.out.println("FillingLoop.run");
}
}
}
class EmptyingLoop implements Runnable {
public void run() {
try {
System.out.println(student2.getName() + " 收拾书包,走向另一个座位");
student2 = exchanger.exchange(student2);
System.out.println("换完座位了,当前座位是: = " + student2);
} catch (InterruptedException ex) {
System.out.println("EmptyingLoop.run");
}
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
public static void main(String[] args) {
FillAndEmpty fillAndEmpty = new FillAndEmpty();
fillAndEmpty.start();
}
}
class Student {
private String name;
private int id;
public Student() {
}
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", id=" + id + '}';
}
}