阿里真题:线程交叉打印
Posted 双斜杠少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿里真题:线程交叉打印相关的知识,希望对你有一定的参考价值。
leetcode 1115. 交替打印FooBar 多线程交替打印
五种方案实现多线程交替打印。
涉及 CyclicBarrier 篱栅、回环屏障 、Semaphore 信号灯、ReentrantLock、synchronized、AtomicBoolean 无锁cas 。
全部都已经在leetCode 提交通过
代码如下:
ReentrantLock 方案
/**
* 方案3 ReentrantLock
*/
class FooBar3
private int n;
public FooBar3(int n)
this.n = n;
ReentrantLock lock = new ReentrantLock(true);
Condition c = lock.newCondition();
volatile boolean flag = true;
public void foo(Runnable printFoo) throws InterruptedException
for (int i = 0; i < n; i++)
lock.lock();
try
if (!flag)
c.await();
printFoo.run();
flag = false;
c.signal();
finally
lock.unlock();
public void bar(Runnable printBar) throws InterruptedException
for (int i = 0; i < n; i++)
lock.lock();
try
if (flag)
c.await();
printBar.run();
flag = true;
c.signal();
finally
lock.unlock();
synchronized 方案
/**
* 方案4 与方案三同理 synchronized
*/
class FooBar4
private int n;
public FooBar4(int n)
this.n = n;
volatile boolean flag = true;
private final Object lock = new Object();
public void foo(Runnable printFoo) throws InterruptedException
for (int i = 0; i < n; i++)
synchronized (lock)
//首次执行放行
if (!flag)
//当前线程挂起
lock.wait();
flag = false;
printFoo.run();
lock.notifyAll();
public void bar(Runnable printBar) throws InterruptedException
for (int i = 0; i < n; i++)
synchronized (lock)
if (flag)
//当前线程挂起
lock.wait();
printBar.run();
flag = true;
lock.notifyAll();
AtomicBoolean 方案 CAS 无锁
/**
* 方案5 无锁方案 cas
*/
class FooBar5
private int n;
public FooBar5(int n)
this.n = n;
AtomicBoolean flag = new AtomicBoolean(true);
public void foo(Runnable printFoo) throws InterruptedException
for (int i = 0; i < n; i++)
while (!flag.get())
Thread.yield();
printFoo.run();
flag.compareAndSet(true, false);
public void bar(Runnable printBar) throws InterruptedException
for (int i = 0; i < n; i++)
while (flag.get())
Thread.yield();
printBar.run();
flag.compareAndSet(false, true);
Semaphore 方案 信号灯
/**
* 方案2 信号灯,相对简单
*/
class FooBar2
private int n;
public FooBar2(int n)
this.n = n;
/**
* semaphore初始化为1个信号量
*/
private Semaphore semaphore = new Semaphore(1);
/**
* semaphore初始化为0个信号量
*/
private Semaphore semaphore2 = new Semaphore(0);
public void foo(Runnable printFoo) throws InterruptedException
for (int i = 0; i < n; i++)
//判断semaphore信号量是否存在
semaphore.acquire();
printFoo.run();
//释放1个semaphore信号量
semaphore2.release();
public void bar(Runnable printBar) throws InterruptedException
for (int i = 0; i < n; i++)
//判断semaphore信号量是否存在
semaphore2.acquire();
printBar.run();
//释放1个semaphore信号量
semaphore.release();
CyclicBarrier 回环屏障
public class FooBar
private int n;
public FooBar(int n)
this.n = n;
private static final CyclicBarrier c = new CyclicBarrier(2);
public void foo(Runnable printFoo) throws InterruptedException
for (int i = 0; i < n; i++)
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
try
c.await();
catch (Exception e)
public void bar(Runnable printBar) throws InterruptedException
for (int i = 0; i < n; i++)
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
try
c.await();
catch (Exception e)
以上是关于阿里真题:线程交叉打印的主要内容,如果未能解决你的问题,请参考以下文章