【Leetcode多线程】- Leetcode1114 按序打印

【Leetcode多线程】- Leetcode1114 按序打印

我们提供了一个类:

public class Foo {
public void first() { print(“first”); }
public void second() { print(“second”); }
public void third() { print(“third”); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。

一个将会调用 first() 方法
一个将会调用 second() 方法
还有一个将会调用 third() 方法
请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。

示例 1:

输入: [1,2,3]
输出: “firstsecondthird”
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 second() 方法,线程 C 将会调用 third() 方法。
正确的输出是 “firstsecondthird”。

解题思路1:自旋 通过条件

class Foo {
    private AtomicInteger firstJobDone  = new AtomicInteger(0);
    private AtomicInteger secondJobDone = new AtomicInteger(0);

    public Foo() {
    }

    public void first(Runnable printFirst) throws InterruptedException {
        
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        firstJobDone.incrementAndGet();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        // 自旋
        while(firstJobDone.get()!=1){

        }
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        secondJobDone.incrementAndGet();
    }

    public void third(Runnable printThird) throws InterruptedException {
        while(secondJobDone.get()!=1){

        }
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
    }
}

解题思路2:用semaphore信号量,信号量为0,用acquire方法会被阻塞,信号量为1,那么就可以被获取,release()之后信号量会自增

class Foo {
    // 用信号量来解题
    private Semaphore spa,spb,spc;
    public Foo() {
        // 如果这个semaphore为0,那么一个线程调用acquire会被阻塞住
        spa = new Semaphore(1);
        spb = new Semaphore(0);
        spc = new Semaphore(0);
    }

    public void first(Runnable printFirst) throws InterruptedException {
        spa.acquire();
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        // 只有first释放semaphore之后,会使得semaphore值为1,另一个线程才可以调用
        spb.release();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        // 只有spa会1才能执行acquire,如果为0就会产生阻塞
        spb.acquire();
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        spc.release();
    }

    public void third(Runnable printThird) throws InterruptedException {
        // 只有spb会1才能通过,如果为0就会阻塞
        spc.acquire();
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
    }
}

countDownLatch

class Foo {

    private CountDownLatch cdla;
    private CountDownLatch cdlb;

    public Foo() {
        cdla = new CountDownLatch(1);
        cdlb = new CountDownLatch(1);    
    }

    public void first(Runnable printFirst) throws InterruptedException {
        
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        // 计算为0
        cdla.countDown();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        // 只有cdla为0才能通过,否则会一直阻塞
        cdla.await();
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        cdlb.countDown();
    }

    public void third(Runnable printThird) throws InterruptedException {
        cdlb.await();
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mind_programmonkey

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值