Skip to content

Latest commit

 

History

History
79 lines (55 loc) · 1.66 KB

2020年06月16日-java-按顺序打印.md

File metadata and controls

79 lines (55 loc) · 1.66 KB

按顺序打印

问题:

我们提供了一个类:

public class Foo {
  public void one() { print("one"); }
  public void two() { print("two"); }
  public void three() { print("three"); }
}

三个不同的线程将会共用一个 Foo 实例。

线程 A 将会调用 one() 方法 线程 B 将会调用 two() 方法 线程 C 将会调用 three() 方法 请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。

解决思路:

  • 设置两个信号量,标识one、two方法两个执行状态
  • 执行对应方法前,检查信号量,不符合就自旋

代码:

package com.learn.othercode.learn.jdbcspace;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

class Foo {
    AtomicBoolean oneIsOk = new AtomicBoolean(false);
    AtomicBoolean twoIsOk = new AtomicBoolean(false);

    public void one() {
        System.out.println("one");
        oneIsOk.compareAndSet(false, true);
    }

    public void two() {
        while (!oneIsOk.get()){
            // 自旋,直到one()执行完成
        }
        System.out.println("two");
        twoIsOk.compareAndSet(false, true);
    }

    public void three() {
        while (!twoIsOk.get()){
            // 自旋,直到one()执行完成
        }
        System.out.println("three");
    }
}

public class Test {

    public static void main(String[] args) {
        Foo foo = new Foo();
        new Thread(() -> foo.three()).start();
        new Thread(() -> foo.one()).start();
        new Thread(() -> foo.two()).start();
    }

}