whether the private member variable value
in class Result
need to be modified by volatile
public class Main {
public static void main(String[] args) throws InterruptedException {
Result result = new Result();
synchronized (result) {
new Thread(new Task1(result)).start();
new Thread(new Task1(result)).start();
new Thread(new Task1(result)).start();
new Thread(new Task1(result)).start();
new Thread(new Task1(result)).start();
new Thread(new Task2(result)).start();
new Thread(new Task2(result)).start();
new Thread(new Task2(result)).start();
new Thread(new Task2(result)).start();
new Thread(new Task2(result)).start();
new Thread(new Task2(result)).start();
result.wait(1500);
}
System.out.println(result.getValue());
System.out.println("Finished");
}
}
class Result {
private Integer value;
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
class Task1 implements Runnable {
private final Result result;
public Task1(Result result) {
this.result = result;
}
@Override
public void run() {
try {
// call function1
Thread.sleep(1010);
if (result.getValue() == null) {
synchronized (result) {
if(result.getValue() == null) {
result.setValue(new Integer(10000));
System.out.println("####: 1");
// throw new InterruptedException();
result.notify();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Task2 implements Runnable {
private final Result result;
public Task2(Result result) {
this.result = result;
}
@Override
public void run() {
try {
// call function2
Thread.sleep(1000);
if (result.getValue() == null) {
synchronized (result) {
if(result.getValue() == null) {
result.setValue(new Integer(2000000));
System.out.println("####: 2");
result.notify();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}