我正在尝试编辑我的程序,以便 incrementer
和 decrementer
类被交替调用,incrementer
首先被执行。我的目标是能够在每个 sharedValue
之后打印共享变量 ( increment
) 的值。/decrement
希望看到它在 1
之间切换和 0
.下面是我的 main
的代码类,一个semaphore
类和 incrementer
类(有一个类 decrementer
的样式与 icrementer
相同,所以我没有包括它)。
主类
public class Main extends Thread {
private static int sharedValue = 0;
private static Semaphore semaphore = new Semaphore(1);
static int numberOfCycles = 20000;
public static void increment() {
semaphore.down();
sharedValue++;
semaphore.up();
}
public static void decrement() {
semaphore.down();
sharedValue--;
semaphore.up();
}
public static void main(String[] args) throws InterruptedException {
incrementer inc = new incrementer(numberOfCycles);
inc.start();
inc.join();
decrementer dec = new decrementer(numberOfCycles);
dec.start();
dec.join();
System.out.println(sharedValue);
}
}
信号量类
private int count;
// Constructor
public Semaphore(int n) {
count = n;
}
// Only the standard up and down operators are allowed.
public synchronized void down() {
while (count == 0) {
try {
wait(); // Blocking call.
} catch (InterruptedException exception) {
}
}
count--;
}
public synchronized void up() {
count++;
notify();
}
增量类
public class incrementer extends Thread{
private int numberOfIncrements;
public incrementer(int numOfIncrements){
numberOfIncrements = numOfIncrements;
}
public void run(){
for(int i = 0; i <= numberOfIncrements; i++){
Main.increment();
}
}
}
提前致谢!
所以我一直在通读我的笔记,我突然想到我可以使用另一个互斥信号量来确定缓冲区是满的还是空的。我对这种方法是否正确?
最佳答案
Thread.Join导致您的主线程等待增量器完成,然后启动减量器,然后等待减量器完成。如果您希望它们同时运行,请删除两个 Thread.Join 调用:
public static void main(String[] args) throws InterruptedException {
incrementer inc = new incrementer(numberOfCycles);
decrementer dec = new decrementer(numberOfCycles);
inc.start();
dec.start();
}
要在每次递增或递减后打印共享值,请将 println 调用移至主类的 increment 和 decrement 函数:
public static void increment() {
semaphore.down();
sharedValue++;
System.out.println(sharedValue);
semaphore.up();
}
public static void decrement() {
semaphore.down();
sharedValue--;
System.out.println(sharedValue);
semaphore.up();
}
另请注意,即使进行了这些更改,您也不会观察到 1 和 0 之间的切换。这是因为两个线程不会同时启动,即使它们启动了(例如使用 CyclicBarrier )您无法控制日程安排,因此他们的进度会有所不同。如果你真的想观察这个输出,你应该让每个线程在调用 semaphore.up() 之前和之后等待 1ms,以便让另一个线程有机会等待并获得信号量的许可。
public static void increment() {
semaphore.down();
sharedValue++;
System.out.println(sharedValue);
try {
Thread.sleep(1); //give time to other threads to wait for permit
semaphore.up();
Thread.sleep(1); //give time to other threads to acquire permit
} catch (InterruptedException ex) {
}
}
有更强大的方法可以从两个线程获得这种输出,但我不想对您的代码进行重大修改。
关于java - 在两个线程之间交替(生产者-消费者),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34250694/