给你一个类:
class FooBar { public void foo() { for (int i = 0; i < n; i++) { print("foo"); } } public void bar() { for (int i = 0; i < n; i++) { print("bar"); } } }
两个不同的线程将会共用一个 FooBar
实例:
- 线程 A 将会调用
foo()
方法,而 - 线程 B 将会调用
bar()
方法
请设计修改程序,以确保 "foobar"
被输出 n
次。
示例 1:
输入:n = 1 输出:"foobar" 解释:这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。
示例 2:
输入:n = 2 输出:"foobarfoobar" 解释:"foobar" 将被输出两次。
package com.example.demo1.service.impl;
import java.util.concurrent.*;
class FooBar {
private int n;
//栅栏 当计数器变成0的时候 就会吧栅栏打开 放行所有线程 否则一直阻塞
CyclicBarrier a=new CyclicBarrier(2);
//在多个线程中 共享变量的可见性
private volatile boolean flag=true;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
while (!flag){
//当状态不是true的时候 就一直自旋 阻塞
}
//先打印foo方法 然后计数器减去1
printFoo.run();
flag=false;
try {
//计数器 减一
a.await();
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
try {
//计数器 减一 1-1=0 那么放行栅栏 打印 bar方法
a.await();
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
printBar.run();
flag=true;
}
}
}
package com.example.demo1.service.impl;
public class Test {
public static void main(String[] args) {
FooBar fooBar=new FooBar(2);
Thread a=new Thread(()->{
try {
fooBar.foo(()->{
System.out.println("aaa");
});
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
Thread b=new Thread(()->{
try {
fooBar.bar(()->{
System.out.println("bbb");
});
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
a.start();
b.start();
}
}
最终交替打印了