由于水平原因,博客大部分内容摘抄于网络,如有错误或者侵权请指出,本人将尽快修改

1114. 按序打印

1114. 按序打印

题目描述

我们提供了一个类:

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"。

示例 2:

输入: [1,3,2]
输出: "firstsecondthird"
解释: 
输入 [1,3,2] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 third() 方法,线程 C 将会调用 second() 方法。
正确的输出是 "firstsecondthird"。

 

提示:

  • 尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
  • 你看到的输入格式主要是为了确保测试的全面性。

解法

JAVA

/**
 // 使用类锁 - 同一时间只有一个线程能执行
 Foo foo1 = new Foo();
 Foo foo2 = new Foo();
 // foo1 和 foo2 的同步方法会互相阻塞

 // 使用实例锁 - 不同实例可以并发执行
 Foo foo1 = new Foo();
 Foo foo2 = new Foo();
 // foo1 和 foo2 的同步方法可以同时执行
 */
class Foo {

    private int cur = 1;

    public Foo() {

    }

    public void first(Runnable printFirst) throws InterruptedException {
        synchronized(Foo.class) {
            while(cur != 1) {
                Foo.class.wait();
            }
            // printFirst.run() outputs "first". Do not change or remove this line.
            printFirst.run();
            cur++;
            Foo.class.notifyAll();
        }
    }

    public void second(Runnable printSecond) throws InterruptedException {
        synchronized(Foo.class) {
            while(cur != 2) {
                Foo.class.wait();
            }
            // printSecond.run() outputs "second". Do not change or remove this line.
            printSecond.run();
            cur++;
            Foo.class.notifyAll();
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        synchronized(Foo.class) {
            while(cur != 3) {
                Foo.class.wait();
            }
            // printThird.run() outputs "third". Do not change or remove this line.
            printThird.run();
            cur++;
            Foo.class.notifyAll();
        }
    }
}

Java

class Foo {
    
    private int cur = 1;
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();

    public Foo() {
        
    }

    public void first(Runnable printFirst) throws InterruptedException {
        lock.lock();
        try {
            while (cur != 1) {
                condition.await();
            }
            printFirst.run();
            cur = 2;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void second(Runnable printSecond) throws InterruptedException {
        lock.lock();
        try {
            while (cur != 2) {
                condition.await();
            }
            printSecond.run();
            cur = 3;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        lock.lock();
        try {
            while (cur != 3) {
                condition.await();
            }
            printThird.run();
            cur = 1;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

...


posted @ 2025-10-22 09:50  小纸条  阅读(5)  评论(0)    收藏  举报