我尝试编辑我的程序,以便交替调用incrementer
和decrementer
类,首先执行incrementer
。我的目标是能够在每个sharedValue
/ increment
之后打印共享变量(decrement
)的值,并希望看到它在1
和{{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();
}
提前致谢!
所以我一直在阅读我的笔记,我发现我可以使用另一个互斥信号量,它可以确定缓冲区是满还是空。我采用这种方法是对的吗?
答案 0 :(得分:1)
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 调用移至主类的增量和减量函数:
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) {
}
}
有更强大的方法可以从两个线程获得此类输出,但我不想对您的代码进行重大修改。