use*_*908 2 java multithreading atomic
我试图使用跨多个线程的共享整数对象按顺序打印从1到10的数字.当使用共享对象作为AtomicInteger时,程序正常工作,但是当使用普通的Integer对象时,程序会抛出异常,我不知道为什么会发生这种情况.
用AtomicInteger编程
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();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
Shared object value is: 1
Shared object value is: 2
Shared object value is: 3
Shared object value is: 4
Shared object value is: 5
Shared object value is: 6
Shared object value is: 7
Shared object value is: 8
Shared object value is: 9
Shared object value is: 10
Run Code Online (Sandbox Code Playgroud)
用普通的Integer对象编程
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();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
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)
Run Code Online (Sandbox Code Playgroud)
this.sharedObject++; 不会做你想象的那样.
由于Integer是不可变的,因此无法更改现有的共享对象.此操作的作用是将值拆分为a int,将其增加,然后将其重新装入另一个Integer实例.
因此,您的代码(几乎*)等效于以下内容:
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);
Run Code Online (Sandbox Code Playgroud)
此时您的对象不再是同一个实例,您的synchronized块将不会与wait()/ notify()calls对齐.
请注意,这与原子性无关AtomicInteger,它只是与++运算符的工作原理有关Integer.
*实际上,您可能会获得一个缓存实例new Integer(),但它仍然是一个不同的实例,因为它代表一个不同的int值.