使用信号量
Using a semaphore
我想知道如何让这些线程一个接一个地工作,以及如何让第一个线程总是 运行 在第二个线程之后。我创建了一个信号量,但我不确定如何使用它。
public class A extends Thread {
private int i;
public A(int x) {
i = x;
}@
Override
public void run() {
System.out.println(i);
}
}
/** 主要内容 **/
A c1 = new A(5);
A c2 = new A(6);
Semaphore s = new Semaphore(1, true);
c1.start();
c2.start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
System.out.println("+");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(70);
} catch (InterruptedException e) {}
System.out.println("*");
}
}
}).start();
您可以将信号量中的许可建模为:"allowed to run"。
由于您希望第一个线程被允许自动 运行,您不能对第一个线程使用 acquire
,因为它会与第二个线程竞争许可。所以第一个线程启动,假设它有许可。当第一个线程完成时,它 release
-es 许可。第二个线程需要 acquire
许可才能开始工作。
首先创建一个具有零许可的信号量(因为第一个线程已经隐式拥有一个许可)
final Semaphore s = new Semaphore(0, true);
第一个线程的最后一行应为:
s.release();
(请注意,它允许在没有获取的情况下发布 - 信号量只是重要的,它不会跟踪谁拥有哪个许可)
第二个话题的第一行应该是:
s.acquireUninterruptibly();
(或者只是 acquire()
但是你需要赶上 InterruptedException
)
- I would like to know how can i make those threads work one after the other, and
- how to make the first one always run after the second one. I created a semaphore, but i not sure about how to use it.
如果您希望线程在调用线程 c2 之前完成,您可以在您的情况下使用 join()
。像这样(线程在 main
的线程中调用):
c1.start(); // Start thread `c1` first
c1.join(); // `main` now waits for `c1` to finish
c2.start(); // Start thread `c2` next
c2.join(); // `main` now waits for `c2` to finish
这应该可以回答您的问题。
我对信号量略知一二。
一般来说,您不能使用信号量来控制线程的执行顺序。信号量是一个或多个资源的锁。想要访问资源的线程相互竞争,您无法控制信号量接下来将访问权授予谁。
我知道另一个答案中的 "trick"。我没有测试它,它可能会起作用,但我认为这不是正确的方法。
这是一个没有信号量的例子:
import java.util.concurrent.Semaphore;
class A extends Thread {
private int i;
public A(int x) {
i = x;
}
public void run() {
System.out.println(i);
}
public static void main(String[] args) throws Exception {
A thread1 = new A(5);
A thread2 = new A(6);
thread1.start();
thread1.join();
thread2.start();
thread2.join();
}
}
如果你想使用信号量(虽然我不明白为什么)那么这个例子可能是这样的:
import java.util.concurrent.Semaphore;
class A extends Thread {
private int i;
final static Semaphore semaphore = new Semaphore(1, true);
public A(int x) {
i = x;
}
public void run() {
try {
/*thread stops here until it gets permit to go on*/
semaphore.acquire();
System.out.println(i);
/*exception must be caught or thrown*/
} catch (InterruptedException e) { }
//CRITICAL SECTION
semaphore.release();
}
public static void main(String[] args) throws Exception {
A thread1 = new A(5);
A thread2 = new A(6);
thread1.start();
thread1.join();
thread2.start();
thread2.join();
}
}
虽然你的问题可以通过线程的 'join' 特性来解决
可以在开始下一个 asi 之前强制完成一个线程(如中所示)
Elyasian 的例子,但仍然必须补充一点,你是在正确的轨道上
就采取的信号量路线而言。
信号量 s = 新信号量(1, true);
在此语句中,设置为 'true' 的第二个参数称为公平设置。
换句话说,在我们的场景中,这确保了(FIFO - 先进先出)"First come First serve" ....
即首先调用 acquire 的线程将获得许可并完成
它的任务首先,然后第二个线程才能继续
它的执行。
所以你原来的问题.....即
我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终运行 在第二个线程之后
可以改写为
我想知道如何确保调用 acquire 的线程
首先在信号量上到达 运行 首先总是....
我想知道如何让这些线程一个接一个地工作,以及如何让第一个线程总是 运行 在第二个线程之后。我创建了一个信号量,但我不确定如何使用它。
public class A extends Thread {
private int i;
public A(int x) {
i = x;
}@
Override
public void run() {
System.out.println(i);
}
}
/** 主要内容 **/
A c1 = new A(5);
A c2 = new A(6);
Semaphore s = new Semaphore(1, true);
c1.start();
c2.start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
System.out.println("+");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(70);
} catch (InterruptedException e) {}
System.out.println("*");
}
}
}).start();
您可以将信号量中的许可建模为:"allowed to run"。
由于您希望第一个线程被允许自动 运行,您不能对第一个线程使用 acquire
,因为它会与第二个线程竞争许可。所以第一个线程启动,假设它有许可。当第一个线程完成时,它 release
-es 许可。第二个线程需要 acquire
许可才能开始工作。
首先创建一个具有零许可的信号量(因为第一个线程已经隐式拥有一个许可)
final Semaphore s = new Semaphore(0, true);
第一个线程的最后一行应为:
s.release();
(请注意,它允许在没有获取的情况下发布 - 信号量只是重要的,它不会跟踪谁拥有哪个许可)
第二个话题的第一行应该是:
s.acquireUninterruptibly();
(或者只是 acquire()
但是你需要赶上 InterruptedException
)
- I would like to know how can i make those threads work one after the other, and
- how to make the first one always run after the second one. I created a semaphore, but i not sure about how to use it.
如果您希望线程在调用线程 c2 之前完成,您可以在您的情况下使用 join()
。像这样(线程在 main
的线程中调用):
c1.start(); // Start thread `c1` first
c1.join(); // `main` now waits for `c1` to finish
c2.start(); // Start thread `c2` next
c2.join(); // `main` now waits for `c2` to finish
这应该可以回答您的问题。
我对信号量略知一二。
一般来说,您不能使用信号量来控制线程的执行顺序。信号量是一个或多个资源的锁。想要访问资源的线程相互竞争,您无法控制信号量接下来将访问权授予谁。
我知道另一个答案中的 "trick"。我没有测试它,它可能会起作用,但我认为这不是正确的方法。
这是一个没有信号量的例子:
import java.util.concurrent.Semaphore;
class A extends Thread {
private int i;
public A(int x) {
i = x;
}
public void run() {
System.out.println(i);
}
public static void main(String[] args) throws Exception {
A thread1 = new A(5);
A thread2 = new A(6);
thread1.start();
thread1.join();
thread2.start();
thread2.join();
}
}
如果你想使用信号量(虽然我不明白为什么)那么这个例子可能是这样的:
import java.util.concurrent.Semaphore;
class A extends Thread {
private int i;
final static Semaphore semaphore = new Semaphore(1, true);
public A(int x) {
i = x;
}
public void run() {
try {
/*thread stops here until it gets permit to go on*/
semaphore.acquire();
System.out.println(i);
/*exception must be caught or thrown*/
} catch (InterruptedException e) { }
//CRITICAL SECTION
semaphore.release();
}
public static void main(String[] args) throws Exception {
A thread1 = new A(5);
A thread2 = new A(6);
thread1.start();
thread1.join();
thread2.start();
thread2.join();
}
}
虽然你的问题可以通过线程的 'join' 特性来解决 可以在开始下一个 asi 之前强制完成一个线程(如中所示) Elyasian 的例子,但仍然必须补充一点,你是在正确的轨道上 就采取的信号量路线而言。
信号量 s = 新信号量(1, true);
在此语句中,设置为 'true' 的第二个参数称为公平设置。
换句话说,在我们的场景中,这确保了(FIFO - 先进先出)"First come First serve" ....
即首先调用 acquire 的线程将获得许可并完成 它的任务首先,然后第二个线程才能继续 它的执行。
所以你原来的问题.....即
我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终运行 在第二个线程之后
可以改写为
我想知道如何确保调用 acquire 的线程 首先在信号量上到达 运行 首先总是....