java-线程执行顺序

wfsdck30  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(356)

我尝试使用信号量严格地依次启动10个线程。也就是说,在执行thread-0之后,应该执行thread-1,而不是thread-2。
但问题是线程到达 semaphore.acquire() -方法出错,因此线程的执行也会出错。如何用信号量解决这个问题而不使用 thread.join() ?

public class Main {

    private Semaphore semaphore = new Semaphore(1, true);

    public static void main(String[] args) {
        new Main().start();
    }

    private void start() {
        for (int i = 0; i < 10; i++) {
            Runnable runnable = () -> {
                try {
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("In run method " + Thread.currentThread().getName());
                semaphore.release();
            };
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }

}

输出:

In run method Thread-0
In run method Thread-1
In run method Thread-4
In run method Thread-5
In run method Thread-3
In run method Thread-2
In run method Thread-6
In run method Thread-7
In run method Thread-9
In run method Thread-8
6vl6ewon

6vl6ewon1#

private void start() {
    final AtomicInteger counter = new AtomicInteger();

    for (int i = 0; i < 10; i++) {
        final int num = i;
        new Thread(() -> {
            while (counter.get() != num) {
            }
            System.out.println("In run method " + Thread.currentThread().getName());
            counter.incrementAndGet();
        }).start();
    }
}
r1zk6ea1

r1zk6ea12#

您需要一个具有某种排序概念的同步对象。如果你熟悉美国的杂货店,不妨考虑一下熟食店柜台上的“记号码”装置,它会告诉你该轮到谁了。
代码草图:

class SyncThing {
   int turn = 0; 
   synchronized void waitForTurn(int me) {
       while (turn != me)
           wait();
   }
   synchronized void nextTurn() {
        turn++;
        notifyAll();
   }
}

然后宣布 SyncThing syncThing = new SyncThing(); 把第1根线穿成这样:

Runnable runnable = () -> {
            syncThing.waitForTurn(i);
            System.out.println("In run method " + Thread.currentThread().getName());
            syncThing.nextTurn();
        };

这是在我的头上键入,并不是作为完整的代码提供,但它应该显示的方式。

相关问题