有没有人知道为什么在编译这段代码后,(我认为)还有一个线程在等待什么? 我想用ID为10,11和12的线程逐一增加计数,直到50。 最后,它工作,但红色按钮(终止)仍然是红色,这意味着它仍在运行的程序,可能还在等待一些东西。
我认为当计数为50时,返回应该起作用并退出方法。也许它确实如此,但还不够。
以下是代码:
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();
}
}
}
答案 0 :(得分:1)
你的问题是你永远不会释放线程上的锁,他们最终会永远等待。
根据您的逻辑,线程A版本B发布C.
但是,一旦你达到50,线程A就会返回。永远不要释放线程B和C.
所以你需要的是一个退出条件释放所有其他等待线程。
例如(在你的while循环中):
if(count == 50) {
sem2.release();
sem3.release();
sem1.release();
}
问题是,一旦11或12增加,他们就会再次进入循环,此时他们会锁定等待被释放的宿舍。如果您的计数为50,则释放它的线程将返回,而不会输入您的if条件。
或者,您应该能够在else子句中添加一个版本,因此所有线程都会被释放。
希望有所帮助,
Artur
编辑:以下是实施修复程序的完整代码:
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,我将释放semathors,以便其他线程可以退出。
答案 1 :(得分:0)
释放锁定以完成线程。
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();
}
}
}