Java 指定线程的信号量增量计数
Java semaphore increment count with specified threads
有人知道为什么在编译这段代码后,(我认为)一个线程仍在等待什么吗?
我想用 id 为 10,11 和 12 的线程一个接一个地递增计数,直到 50。
最后,它工作了,但是红色按钮(终止)仍然是红色的,这意味着程序它仍然是 运行,并且可能在等待什么。
我认为当计数为 50 时,return 应该工作并退出方法。也许是,但还不够。
代码如下:
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem2.release();
} else
return;
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem3.release();
} else
return;
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem1.release();
} else
return;
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th1 = new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th1.start();
}
}
}
你的问题是你永远不会释放线程上的锁,它们最终会永远等待。
按照你的逻辑,线程A释放B释放C。
但是,一旦达到 50,线程 A returns。从不释放线程 B 和 C。
所以你需要的是一个释放所有其他等待线程的退出条件。
例如(在你的 while 循环中):
if(count == 50) {
sem2.release();
sem3.release();
sem1.release();
}
问题是,一旦增加 11 或 12,它们就会立即再次进入循环,此时它们会锁定等待释放的信号。但是,如果您的计数是 50,则释放它的线程将 return 而不会进入您的 if 条件。
或者,您应该能够在 else 子句上添加释放,以便释放所有线程。
希望对您有所帮助,
阿图尔
编辑:这是您实施修复的完整代码:
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem2.release();
} else {
sem2.release();
return;
}
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem3.release();
} else {
sem3.release();
return;
}
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem1.release();
} else {
sem1.release();
return;
}
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th1 = new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
System.out.println("Exist ");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th1.start();
}
}
}
注意:一旦计数达到 50,我将释放信号器,以便其他线程可以退出。
释放锁以完成线程。
import java.util.concurrent.Semaphore;
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem2.release();
return;
}
sem2.release();
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem3.release();
return;
}
sem3.release();
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem1.release();
return;
}
sem1.release();
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th= new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th.start();
}
}
}
有人知道为什么在编译这段代码后,(我认为)一个线程仍在等待什么吗? 我想用 id 为 10,11 和 12 的线程一个接一个地递增计数,直到 50。 最后,它工作了,但是红色按钮(终止)仍然是红色的,这意味着程序它仍然是 运行,并且可能在等待什么。
我认为当计数为 50 时,return 应该工作并退出方法。也许是,但还不够。
代码如下:
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem2.release();
} else
return;
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem3.release();
} else
return;
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
sem1.release();
} else
return;
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th1 = new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th1.start();
}
}
}
你的问题是你永远不会释放线程上的锁,它们最终会永远等待。
按照你的逻辑,线程A释放B释放C。
但是,一旦达到 50,线程 A returns。从不释放线程 B 和 C。
所以你需要的是一个释放所有其他等待线程的退出条件。
例如(在你的 while 循环中):
if(count == 50) {
sem2.release();
sem3.release();
sem1.release();
}
问题是,一旦增加 11 或 12,它们就会立即再次进入循环,此时它们会锁定等待释放的信号。但是,如果您的计数是 50,则释放它的线程将 return 而不会进入您的 if 条件。
或者,您应该能够在 else 子句上添加释放,以便释放所有线程。
希望对您有所帮助,
阿图尔
编辑:这是您实施修复的完整代码:
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem2.release();
} else {
sem2.release();
return;
}
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem3.release();
} else {
sem3.release();
return;
}
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
sem1.release();
} else {
sem1.release();
return;
}
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th1 = new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
System.out.println("Exist ");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th1.start();
}
}
}
注意:一旦计数达到 50,我将释放信号器,以便其他线程可以退出。
释放锁以完成线程。
import java.util.concurrent.Semaphore;
public class App12 {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
int count = 0;
public void inc() throws InterruptedException {
while (true) {
if (Thread.currentThread().getId() == 10) {
sem1.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem2.release();
return;
}
sem2.release();
}
if (Thread.currentThread().getId() == 11) {
sem2.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem3.release();
return;
}
sem3.release();
}
if (Thread.currentThread().getId() == 12) {
sem3.acquire();
if (count != 50) {
count++;
System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);
} else {
sem1.release();
return;
}
sem1.release();
}
}
}
public static void main(String[] args) {
App12 ap = new App12();
for (int i = 0; i < 3; i++) {
Thread th= new Thread(new Runnable() {
public void run() {
try {
ap.inc();
// dec3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th.start();
}
}
}