带有共享整数对象的Java等待通知
我试图在多个线程中使用共享整数对象按顺序打印从1到10的数字。当使用共享对象作为AtomicInteger时,程序工作正常,但当使用普通整数对象时,程序抛出异常,我不知道为什么会发生这种情况 原子整数程序带有共享整数对象的Java等待通知,java,multithreading,atomic,Java,Multithreading,Atomic,我试图在多个线程中使用共享整数对象按顺序打印从1到10的数字。当使用共享对象作为AtomicInteger时,程序工作正常,但当使用普通整数对象时,程序抛出异常,我不知道为什么会发生这种情况 原子整数程序 import java.util.concurrent.atomic.AtomicInteger; public class ThreadingProblem { public static void main(String[] args) { AtomicIntege
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadingProblem {
public static void main(String[] args) {
AtomicInteger sharedInt = new AtomicInteger(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingPrintingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
@Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingIncrementingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
@Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject.get() < 10) {
this.sharedObject.incrementAndGet();
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
具有普通整数对象的程序
public class ThreadingProblem {
public static void main(String[] args) {
Integer sharedInt = new Integer(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private Integer sharedObject;
public ThreadingPrintingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
@Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private Integer sharedObject;
public ThreadingIncrementingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
@Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject < 10) {
this.sharedObject++;
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
this.sharedObject++代码>不会执行您认为它会执行的操作
由于Integer
是不可变的,因此它不能更改现有的共享对象。相反,此操作所做的是将值取消装箱到一个int
,增加值,然后将其装箱回另一个Integer
实例
因此,您的代码(几乎*)相当于以下代码:
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);
由于此时您的对象不再是同一实例,因此您的synchronized
块将不会与wait()
/notify()
调用对齐
请注意,这与AtomicInteger
的原子性无关,只是与++
操作符如何处理整数有关
*实际上,您可能会得到一个缓存实例,而不是newinteger()
,但它仍然是一个不同的实例,因为它表示不同的int
值
Exception in thread "IncrementerThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.itiviti.apps.catalys.shared.mock.ThreadingIncrementingTask.run(ThreadingProblem.java:52)
at java.lang.Thread.run(Unknown Source)
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);