我想在Java中实现自己的信号量(仅用于练习,我知道,有Semaphore类) 我已经实现了它:
public class MySemaphore {
private int value = 1;
public synchronized void take() {
this.value++;
this.notify();
}
public synchronized void release(){
while (this.value == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.value--;
}
}
我试图在这样的线程中使用它:
public class MyThread extends Thread {
private static MySemaphore semaphore = new MySemaphore();
public void run(){
for (int i = 0; i < 100; i++) {
semaphore.take();
try {
Main.myVariable += 1;
semaphore.release();
} catch (Exception e){
System.out.println("Exception" + e.getMessage());
}
}
}
}
我开始并加入这样的线程:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static int myVariable = 0;
private static int threadsNumber = 100;
public static void main(String[] args) {
List<Thread> allThreads = new ArrayList<>();
for (int i = 0; i < threadsNumber; i++) {
allThreads.add(new Thread(new MyThread()));
}
for (int i = 0; i < threadsNumber; i++) {
allThreads.get(i).start();
}
for (int i = 0; i < threadsNumber; i++) {
try{
allThreads.get(i).join();
} catch (Exception e){
System.out.println(e.getMessage());
System.out.println("********************************");
}
}
System.out.println("Result is " + myVariable);
}
}
我只想将变量增加10000次并收到结果。没有信号量,结果小于10000(如9923,9684),这是由非增量原子性引起的。我想用信号量保护这个变量 不幸的是,结果仍然小于或等于10000(但更接近,10个案例中的9个大于9990)。 你知道为什么会这样吗?我的信号量是错误的还是在启动线程时出错?
答案 0 :(得分:-1)
在MySemaphore类中,值已设置为1.它应该为零,因为在您的释放函数中,您将验证值是否等于零。这意味着当你的程序启动时,没有线程可以拥有信号量(因为你已经将它设置为1);这样做,他们陷入等待状态。当'threadsNumber'达到它的限制时,你的程序结束。换句话说,你没有在程序结束之前验证是否有任何线程处于等待状态。这就解释了为什么你有9/10的成功率。
我的建议是尝试将值设置为零,并验证是否有任何线程处于等待状态。
您的代码是这样的:
public class MySemaphore {
private int value = 0; //this is already an error in your code
public synchronized void take() {
this.value++;
this.notify(); // wakes up the first thread that called wait on the shared variable
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.value--;
}
}