java - 在两个线程之间交替(生产者-消费者)

标签 java

我正在尝试编辑我的程序,以便 incrementerdecrementer类被交替调用,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 调用移至主类的 incrementdecrement 函数:

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/

相关文章:

java - 在intellij中调试测试用例的热键?

32bit-64bit - 在 32 位模式下调试 java 应用程序

java - 程序编译时如何打印堆栈跟踪?

java - 拆分 SurfaceView - Android/Java

java - 有没有办法正确取消 Azure 或 AWS 中的 mysql 查询?

java - 字符串正则表达式解析数据中的分号

java - SetTestProviderLocation 错误...尽管所有参数都未设置位置?

java - Handler.postDelayed 对比 Runnable.run。可以调用 .run 而不是 .postDelayed 吗?

java - Mac笔记本电脑使用和开发讨论?

java - 如何使用正则表达式验证电话号码?