java多线程 六脉神剑
- BlockingQueue
- 信号量Semaphore
- synchronized + 标志位 + 唤醒
- ReentrantLock + Condition
- 自旋yield()让出CPU
- CyclicBarrier控制先后 或使用CountDownLatch+CyclicBarrier
解决下列问题
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实例 其中一个线程调用foo() 另一个线程调用bar()
设计修改程序,保证“foobar”被输出n次
示例: 输入n=2 输出 “foobarfoobar”
1.利用BlockingQueue
class Foobar{
private int n;
private BlockingQueue<Integer> bar = new LinkedBlockingQueue<>(1);
private BlockingQueue<Integer> foo = new LinkedBlockingQueue<>(1);
public FooBar(int n){
this.n= n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
foo.put(i);
printFoo.run();
bar.put(i);
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
bar.take();
printBar.run();
foo.take();
}
}
}
2.利用Semaphore
class FooBar{
private int n;
private Semaphore foo = new Semaphore(1);
private Semaphore bar = new Semaphore(0);
public FooBar(int n){
this.n= n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
foo.acquire();
printFoo.run();
bar.release();
}
}
public void bar(Runnable printBar)throws InterruptedExceptions{
for(int i=0;i<n;i++){
bar.acquire();
printBar.run();
foo.release();
}
}
}
3.利用synchronized + 标志位 + 唤醒
class FooBar{
private int n;
private volatile boolean type = true;
private Object foo = new Object();
public FooBar(int n){
this.n=n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
synchronized(foo){
while(!type){
foo.wait();
}
printFoo.run();
type = false;
foo.notifyAll();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
synchronized(foo){
while(type){
foo.wait();
}
printBar.run();
type= true;
foo.notifyAll();
}
}
}
}
4.利用可重入锁ReentrantLock+Condition
class FooBar{
private int n;
private Lock lock = new ReentrantLock(true);
private final Condition foo = lock.newCondition();
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++){
lock.lock();
try{
while(!flag){
foo.await();
}
printFoo.run();
flag=false;
foo.signal();
}finally{
lock.unlock();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
lock.lock();
try{
while(flag){
foo.await();
}
printBar.run();
flag= true;
foo.signal();
}finally{
lock.unlock();
}
}
}
}
5.利用自旋让出CPU
class FooBar{
private int n;
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;){
if(flag){
printFoo.run();
i++;
flag= false;
}else{
Thread.yield();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;){
if(!flag){
printBar.run();
i++;
flag = true;
}else{
Thread.yield();
}
}
}
}
6.利用CyclicBarrier控制先后
class FooBar{
private int n;
volatile boolean flag = true;
CyclicBarrier cb = new CyclicBarrier(2);
public FooBar(int n){
this.n=n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i = 0;i<n;i++){
while(!flag);
printFoo.run();
flag=false;
try{
cb.await();
}catach(Exception e){
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
try{
cb.await();
}catch(Exception e){
}
printBar.run();
flag=true;
}
}
}
利用CountDownLatch保证任务执行的先后顺序,CyclicBarrier保证任务按组进行
class FooBar{
private int n;
private CountDownLatch a;
private CyclicBarrier barrier;
public FooBar(int n){
this.n=n;
a = new CountDownLatch(1);
barrier= new CyclicBarrier(2);
}
public void foo(Runnable printFoo)throws InterruptedException{
try{
for(int i=0;i<n;i++){
printFoo.run();
a.countDown();
barrier.await();
}
}catch(Exception e){
}
}
public void bar(Runnable printBar)throws InterruptedException{
try{
for(int i=0;i<n;i++){
a.await();
printBar.run();
a = new CountDownLatch(1);
barrier.await();
}
}catch(Exception e){
}
}
}