英文:
Java - the thread execution order
问题
以下是翻译好的部分:
我正在尝试使用信号量(semaphore)严格按顺序启动10个线程。也就是说,在执行线程0后,应该执行线程1,但不是线程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("在 run 方法中:" + Thread.currentThread().getName());
semaphore.release();
};
Thread thread = new Thread(runnable);
thread.start();
}
}
}
输出:
在 run 方法中:Thread-0
在 run 方法中:Thread-1
在 run 方法中:Thread-4
在 run 方法中:Thread-5
在 run 方法中:Thread-3
在 run 方法中:Thread-2
在 run 方法中:Thread-6
在 run 方法中:Thread-7
在 run 方法中:Thread-9
在 run 方法中:Thread-8
英文:
I am trying to start 10 threads strictly in turn using a semaphore.
That is, after the execution of thread-0, thread-1 should be executed, but not thread-2.
But the problem is that the threads is arrives to the semaphore.acquire()
-method in out of order, and therefore the execution of the threads is out of order.
How can I solve this problem with semaphore but without using 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();
}
}
}
Output:
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
</details>
# 答案1
**得分**: 2
你需要一个带有某种排序概念的同步对象。如果你熟悉美国的杂货店,可以考虑在熟食柜台上的“取号”设备,它告诉你轮到谁了。
代码草图:
```java
class SyncThing {
int turn = 0;
synchronized void waitForTurn(int me) {
while (turn != me)
wait();
}
synchronized void nextTurn() {
turn++;
notifyAll();
}
}
然后声明 SyncThing syncThing = new SyncThing();
并且以如下方式运行第 i 个线程:
Runnable runnable = () -> {
syncThing.waitForTurn(i);
System.out.println("In run method " + Thread.currentThread().getName());
syncThing.nextTurn();
};
这是我凭记忆输入的,并不是完整的代码,但应该能够指导方向。
英文:
You need a synchronization object with some sort of concept of ordering. If you're familiar with US grocery stores, consider the "take a number" device at the deli counter that tells you whose turn it is.
Rough sketch of code:
class SyncThing {
int turn = 0;
synchronized void waitForTurn(int me) {
while (turn != me)
wait();
}
synchronized void nextTurn() {
turn++;
notifyAll();
}
}
then declare SyncThing syncThing = new SyncThing();
and run the i'th thread thus:
Runnable runnable = () -> {
syncThing.waitForTurn(i);
System.out.println("In run method " + Thread.currentThread().getName());
syncThing.nextTurn();
};
This is typed in off the top of my head and is not offered as complete code, but it should show the way.
答案2
得分: 0
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("在运行方法中 " + Thread.currentThread().getName());
counter.incrementAndGet();
}).start();
}
}
英文:
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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论