同步使用 java
synchronization usage java
如果我删除“synchronized”,将不会打印“Wait 3 seconds and exit”。
但是如果我添加“System.out.println(getStarted());”或“System.out.println(123);”...在 while 循环内,将打印“等待 3 秒并退出”。
我想知道为什么
public class Consistent {
static boolean started = false;
public synchronized static void setStarted() { //delete synchronized
started = true;
}
public synchronized static boolean getStarted() {//delete synchronized
return started;
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
setStarted();
System.out.println("started set to true");
}
});
thread1.start();
while (!getStarted()) {
// wait until started
// System.out.println(getStarted());
}
System.out.println("Wait 3 seconds and exit");
}
}
如果没有 synchronized
,则无法保证一个线程所做的修改对同步同一对象的其他线程可见。这是因为 Java 内存模型定义了编译器和运行时如何重新排列 reads/writes 变量,以及如何优化事物。 while 循环可能会获得 started
的值一次并保留它。使用 synchronized
,一个线程对变量所做的修改对所有其他线程都是可见的。
当您将 println 移动到 while
循环中时,您会引入额外的同步,因为 println
在内部使用 synchronized
内存访问。
这可能有帮助:http://tutorials.jenkov.com/java-concurrency/java-memory-model.html
如果我删除“synchronized”,将不会打印“Wait 3 seconds and exit”。
但是如果我添加“System.out.println(getStarted());”或“System.out.println(123);”...在 while 循环内,将打印“等待 3 秒并退出”。
我想知道为什么
public class Consistent {
static boolean started = false;
public synchronized static void setStarted() { //delete synchronized
started = true;
}
public synchronized static boolean getStarted() {//delete synchronized
return started;
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
setStarted();
System.out.println("started set to true");
}
});
thread1.start();
while (!getStarted()) {
// wait until started
// System.out.println(getStarted());
}
System.out.println("Wait 3 seconds and exit");
}
}
如果没有 synchronized
,则无法保证一个线程所做的修改对同步同一对象的其他线程可见。这是因为 Java 内存模型定义了编译器和运行时如何重新排列 reads/writes 变量,以及如何优化事物。 while 循环可能会获得 started
的值一次并保留它。使用 synchronized
,一个线程对变量所做的修改对所有其他线程都是可见的。
当您将 println 移动到 while
循环中时,您会引入额外的同步,因为 println
在内部使用 synchronized
内存访问。
这可能有帮助:http://tutorials.jenkov.com/java-concurrency/java-memory-model.html