Java 并行同步 2 个线程

Java synchronize 2 threads in parallel

----------------已解决,谢谢您的建议! ------------

我有以下代码,其中有一个数字数组。我想创建 2 个并行执行的线程。第一个线程打印数值,第二个线程相乘。 这是我的代码

class Synchronize {

    private boolean writeable = true;

    public synchronized void numbers() {
        {
            while (!writeable) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
            writeable = false;
            notify();
        }
    }

    public synchronized void multiply() {
        while (writeable) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        writeable = true;
        notify();
    }
}

class Numbers
        extends Thread {

    private Synchronize s;
    int   numbers = 0;
    int[] array;

    Numbers(String name, Synchronize s, int[] array) {
        super(name);
        this.s = s;
        this.array = array;
    }

    public void run() {
        try {
            for (int i = 0; i <= array.length - 1; i++) {
                System.out.print("\nIn " + getName() + " number is " + array[i] + "\t");
                Thread.sleep(1000);
                s.numbers();
            }
        } catch (Exception e) {
        }
    }
}


class Multiply
        extends Thread {

    private Synchronize s;
    int   multiply = 1;
    int[] array;

    Multiply(String name, Synchronize s, int array[]) {
        super(name);
        this.s = s;
        this.array = array;
    }

    public void run() {
        try {
            for (int i = 0; i <= array.length - 1; i++) {
                multiply = multiply * array[i];
                System.out.print("\nIn " + getName() + " multiply is " + multiply + "\t");
                Thread.sleep(1000);
                s.multiply();
            }
        } catch (Exception e) {
        }
    }
}


public class NewThread {

    public static void main(String[] args) {

        int array[] = {
                1,
                4,
                5,
                2,
                7,
                8,
                9
        };

        Synchronize s = new Synchronize();
        new Numbers("Thread #1 ", s, array).start();
        new Multiply("Thread #2 ", s, array).start();
    }
}

代码输出如下:

In Thread #1  number is 1   
In Thread #2  multiply is 1     
In Thread #1  number is 4   
In Thread #2  multiply is 4     
In Thread #2  multiply is 20    
In Thread #1  number is 5   
In Thread #1  number is 2   
In Thread #2  multiply is 40    
In Thread #1  number is 7
In Thread #1  number is 8   
In Thread #2  multiply is 280   
In Thread #2  multiply is 2240  
In Thread #1  number is 9   
In Thread #2  multiply is 20160 

我希望它成为什么样子

In Thread #1  number is 1   
In Thread #2  multiply is 1   
In Thread #1  number is 4   
In Thread #2  multiply is 4     
In Thread #1  number is 5
In Thread #2  multiply is 20    
In Thread #1  number is 2   
In Thread #2  multiply is 40    
In Thread #1  number is 7   
In Thread #2  multiply is 280   
In Thread #1  number is 8   
In Thread #2  multiply is 2240  
In Thread #1  number is 9   
In Thread #2  multiply is 20160 

我不需要队列方法...如果有人知道该怎么做,我只想修改这段代码。

问题是 System.out.println() 在同步块之外,因此尽管评估已正确序列化,但打印结果可能会调换顺序。

你可以做的是将 System.out.println() 包装到 Runnable 中,将其传递给 numbers(Runnable printer)multiply(Runnable printer) 并从同步中调用 printer.run()方法。

替代解决方案是使用我在评论中提到的 flush

            System.out.print("\nIn " + getName() + " number is " + array[i] + "\t");
            System.out.flush();

注意:有趣的是,在 Eclipse 中 IDE 它在打印到控制台时是同步的,而在命令行上却不是(如果有人想测试的话)。

我觉得没必要用你的 Synchronize class

您正在同步方法 numbers()multiply(),因为根据您的锁 main 方法,这两个方法不会被两个线程调用,除非该程序从外部启动超过一次。所以没有必要让它们同步。

因为交替打印仅在每个线程中通过此语句 Thread.sleep(1000) 发生 class(不是所有时间,而是某些时候),它不会一直交替打印,因为它取决于第二个线程在其他线程的 Thread.sleep() 中提到的时间内完成其任务。

如果您想尝试,可以在 classes

中注释这些行
   s.numbers()
   s.multiply()

你仍然可以至少看到一次预期的输出,