在 java 中跨 类 同步
synchronized across classes in java
我同时有两个线程运行,一个主线程,和一个class旧的布尔变量,我目前有一个线程打印赔率,另一个打印偶数,但我我让他们互相等待,以便按顺序打印 1 - 100。
我目前正在我的 NumberPrinter class 中引用一个布尔对象,我正在使用它使一个线程进入等待状态以等待另一个线程。我知道如何在同一个 class 中进行同步,但是当我尝试跨线程进行同步时,它只是挂起并且看起来布尔变量没有被更新或与两个线程同步。至少这就是我认为问题所在的原因
感谢任何建议
我的测试class
public class Test {
public static void main(String[] args) throws InterruptedException {
NumberPrinter np = new NumberPrinter();
single ent = new single(np);// new state
Double ont = new Double(np);// new state
ent.start();
ont.start();
}
}
class偶数
public class single extends Thread {
private NumberPrinter printer;
public single(NumberPrinter np) {
this.printer = np;
}
public synchronized void run() {
try {
for (int i = 1; i <= 100; i++) {
System.out.println(printer.isOdd);
if (i % 2 == 0) {
if (printer.isOdd == true) {
wait();
}
System.out.println(i);
printer.isOdd = true;
notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class 为奇数
public class Double extends Thread {
private NumberPrinter printer;
public Double(NumberPrinter np) {
this.printer = np;
}
public synchronized void run() {
try {
for (int i = 1; i <= 100; i++) {
System.out.println(printer.isOdd);
if (i % 2 == 1) {
if (printer.isOdd == false) {
wait();
}
System.out.println(getName() + ": " + i);
printer.isOdd = false;
notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
a class 保存布尔变量
package single;
public class NumberPrinter {
public boolean isOdd = true;
}
wait
和 notifyAll
需要从两个线程对同一个对象调用。您还需要在该对象上进行同步。您正在使用线程实例,但有两个不同的实例。您可以为此使用 printer
对象,或者您可以创建一个 new Object()
并使用它。 wait
也应该在 while 循环中使用而不是 if 语句。
public void run() {
try {
for (int i = 1; i <= 100; i++) {
synchronized(printer) {
System.out.println(printer.isOdd);
if (i % 2 == 1) {
while (printer.isOdd == false) {
printer.wait();
}
System.out.println(getName() + ": " + i);
printer.isOdd = false;
printer.notifyAll();
}
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我同时有两个线程运行,一个主线程,和一个class旧的布尔变量,我目前有一个线程打印赔率,另一个打印偶数,但我我让他们互相等待,以便按顺序打印 1 - 100。
我目前正在我的 NumberPrinter class 中引用一个布尔对象,我正在使用它使一个线程进入等待状态以等待另一个线程。我知道如何在同一个 class 中进行同步,但是当我尝试跨线程进行同步时,它只是挂起并且看起来布尔变量没有被更新或与两个线程同步。至少这就是我认为问题所在的原因
感谢任何建议
我的测试class
public class Test {
public static void main(String[] args) throws InterruptedException {
NumberPrinter np = new NumberPrinter();
single ent = new single(np);// new state
Double ont = new Double(np);// new state
ent.start();
ont.start();
}
}
class偶数
public class single extends Thread {
private NumberPrinter printer;
public single(NumberPrinter np) {
this.printer = np;
}
public synchronized void run() {
try {
for (int i = 1; i <= 100; i++) {
System.out.println(printer.isOdd);
if (i % 2 == 0) {
if (printer.isOdd == true) {
wait();
}
System.out.println(i);
printer.isOdd = true;
notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class 为奇数
public class Double extends Thread {
private NumberPrinter printer;
public Double(NumberPrinter np) {
this.printer = np;
}
public synchronized void run() {
try {
for (int i = 1; i <= 100; i++) {
System.out.println(printer.isOdd);
if (i % 2 == 1) {
if (printer.isOdd == false) {
wait();
}
System.out.println(getName() + ": " + i);
printer.isOdd = false;
notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
a class 保存布尔变量
package single;
public class NumberPrinter {
public boolean isOdd = true;
}
wait
和 notifyAll
需要从两个线程对同一个对象调用。您还需要在该对象上进行同步。您正在使用线程实例,但有两个不同的实例。您可以为此使用 printer
对象,或者您可以创建一个 new Object()
并使用它。 wait
也应该在 while 循环中使用而不是 if 语句。
public void run() {
try {
for (int i = 1; i <= 100; i++) {
synchronized(printer) {
System.out.println(printer.isOdd);
if (i % 2 == 1) {
while (printer.isOdd == false) {
printer.wait();
}
System.out.println(getName() + ": " + i);
printer.isOdd = false;
printer.notifyAll();
}
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}