Java 使用信号量
我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终在第二个线程之后运行。我创建了一个信号量,但我不确定如何使用它Java 使用信号量,java,multithreading,semaphore,Java,Multithreading,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
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,因为它将与第二个线程竞争许可。所以第一个线程开始,假设它有许可证。当第一个螺纹完成时,它将释放许可证。第二个螺纹需要获得许可才能开始工作 首先创建一个许可证为零的信号量,因为第一个线程已经隐式拥有一个许可证
final Semaphore s = new Semaphore(0, true);
第一个线程中的最后一行应为:
s.release();
s.acquireUninterruptibly();
请注意,它可以在没有获取的情况下发布-信号量只是计数,它不跟踪谁拥有哪个许可
第二个线程中的第一行应为:
s.release();
s.acquireUninterruptibly();
或者只是获取,但是你需要捕捉中断异常
我想知道如何使这些线程一个接一个地工作,以及
如何使第一个始终在第二个之后运行。我创建了一个信号量,但我不确定如何使用它。
如果希望线程在调用线程c2之前完成,可以在本例中使用join。与此类似,在main的线程中调用线程:
这应该能回答你的问题
我对信号灯有点了解
通常,您不能使用信号量来控制线程的执行顺序。信号量是一个或多个资源的锁。想要访问资源的线程正在相互竞争,您无法控制下一个信号量将向谁授予访问权
我知道另一个答案的诀窍。我没有测试它,它可能会工作,但我认为这不是正确的方法
下面是一个不使用sempahore的示例:
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();
}
}
虽然您的问题可以通过线程的“连接”功能解决 可以在启动下一个asi之前强制完成一个线程,如中所示 Elyasian的例子,但仍然有一个必须补充的是,你在正确的轨道上 就信号量路由而言 信号量s=新信号量1,true 在此语句中,设置为“true”的第二个参数称为公平性设置 这确保了先进先出,换句话说,在我们的场景中,先到先得 即首先调用acquire的线程将获得许可并完成 它的任务是第一个线程,只有第二个线程才能继续执行 它的执行 所以你最初的问题是 我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终在第二个线程之后运行 可以改为 我想知道如何确保调用acquire的线程
信号量上的第一个总是先运行…一个接一个=顺序。你为什么想要多个线程?让我练习控制线程这毫无意义。开始第一个线程。加入吧。然后开始第二个线程。那就加入吧。这里没有理由使用信号灯。@SotiriosDelimanolis是正确的。但是,如果你只是想学习信号量,这是一个不错的起点:我不确定你想要实现什么。你能解释一下你想要的执行命令吗?前两行我不清楚。Sry,我不在家。在我的例子中,有c1和c2线程可以用join组织;正如你所说。现在我明白了。但在main中还有两个“新线程”可以自行执行。这里需要信号量,因为没有实例名称可用于连接方法。以您的例子,我也设法控制了它们,谢谢您,先生。在这种情况下,请使用带有公平选项的二进制信号量。如果答案有助于您解决问题,请随时投票并接受。