-----------------已解决,谢谢您的建议! ------------
我有以下代码,其中有一组数字。我想创建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
我不想要带队列的方法......如果有人知道该怎么做,我想修改这段代码。
答案 0 :(得分:2)
问题是System.out.println()
在同步块之外,因此虽然评估已正确序列化,但打印结果可能会交换订单。
您可以做的是将System.out.println()
打包到Runnable
,将其传递给numbers(Runnable printer)
和multiply(Runnable printer)
,然后从同步方法中调用printer.run()
。
答案 1 :(得分:0)
替代解决方案是使用我在评论中提到的flush
。
System.out.print("\nIn " + getName() + " number is " + array[i] + "\t");
System.out.flush();
注意:有趣的是,在Eclipse IDE中,它在打印到控制台时是同步的,而在命令行上则没有(如果有人想测试它)。
答案 2 :(得分:0)
我认为无需使用您的Synchronize
类
您正在同步方法numbers()
和multiply()
,因为根据您的锁main
方法,两个线程不会调用这两个方法,除非此程序在外部多次启动。所以没有必要让它们成为同步的。
对于打印,替代只发生在每个线程类中的此语句Thread.sleep(1000)
(并非所有时间,但有时),它不会一直打印,因为它依赖于第二个线程来完成其任务在其他主题的Thread.sleep()
中提到的时间内。
如果您想尝试,可以在两个类
中注释这些行 s.numbers()
s.multiply()
仍然可以看到预期的输出至少一次,