Print in Order

Posted on By ᵇᵒ

LeetCode 1114

Print in Order

// java
import java.util.concurrent.*;
class Foo {
    Semaphore run2, run3;

    public Foo() {
        run2 = new Semaphore(0);
        run3 = new Semaphore(0);
    }

    public void first(Runnable printFirst) throws InterruptedException {
        printFirst.run();
        run2.release();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        run2.acquire();
        printSecond.run();
        run3.release();
    }

    public void third(Runnable printThird) throws InterruptedException {
        run3.acquire(); 
        printThird.run();
    }
}

另外,还有使用 ReentrantLock Condition 以及 AtomicInteger 的方式。

阿里面试题

四个线程,串行执行依次打印数字1到1000

线程1打印:1 5 9 …
线程2打印:2 6 10 …
线程3打印:3 7 11 …
线程4打印:4 8 12 …

最后打印的结果:1 2 3 4 5 6 7 8 9 …

// java
public static void main(String[] args) {
    final int NUMBER_SIZE = 1000;
    final int THREAD_SIZE = 4;

    List<Semaphore> semaphores = new ArrayList<>();
    for (int i = 0; i < THREAD_SIZE; i++) {
        semaphores.add(new Semaphore(i == 0 ? 1 : 0));
    }

    List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < THREAD_SIZE; i++) {
        final int index = i;
        Thread t = new Thread(() -> {
            int n = 0;
            while (n < NUMBER_SIZE / THREAD_SIZE) {
                try {
                    semaphores.get(index).acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(index + n * THREAD_SIZE + 1);
                n++;
                semaphores.get((index + 1) % THREAD_SIZE).release();
            }
            if (NUMBER_SIZE % THREAD_SIZE != 0 && index + n * THREAD_SIZE < NUMBER_SIZE) {
                try {
                    semaphores.get(index).acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(index + n * THREAD_SIZE + 1);
                semaphores.get((index + 1) % THREAD_SIZE).release();
            }
        });
        threads.add(t);
    }

    for (int i = 0; i < THREAD_SIZE; i++) {
        threads.get(i).start();
    }
}
// kotlin
fun main() {
    print(1000, 4)
}

fun print(numberSize: Int, threadSize: Int) {
    val semaphores: MutableList<Semaphore> = MutableList(threadSize) {
        Semaphore(if (it == 0) 1 else 0)
    }

    val threads: MutableList<Thread> = MutableList(threadSize) {
        Thread {
            var n = 0
            while (n < numberSize / threadSize) {
                try {
                    semaphores[it].acquire()
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
                println(it + n * threadSize + 1)
                n++
                semaphores[(it + 1) % threadSize].release()
            }
            if (numberSize % threadSize != 0 && it + n * threadSize < numberSize) {
                try {
                    semaphores[it].acquire()
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
                println(it + n * threadSize + 1)
                semaphores[(it + 1) % threadSize].release()
            }
        }
    }

    for (i in 0 until threadSize) {
        threads[i].start()
    }
}