如何正确同步/锁定变量?
How to Synchronizing / Locking a Variable right?
我无法理解 Java 中的 synchronized(){}。不知何故,我认为 synchronized(this) 我锁定了 Class 的 THIS 实例,如果我想访问一个属性或从另一个线程调用这个特定实例的函数,那么另一个线程必须等到 synchronized 结束。不知何故,在此示例代码中它不起作用。
我想让线程 A 等到线程 B 做某事后再继续。
public class A implements Runnable{
public void start(){
Thread t = new Thread(this);
t.start();
}
public void run(){
B b = new B();
b.start();
//DO STUFF
while(b.loaded){
//WAIT FOR B DOING STUFF
}
//GO ON DOING STUFF
}
}
public class B implements Runnable {
public boolean loaded;
public B(){
loaded = false;
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
public void run(){
//DOING STUFF
synchronized (this){
loaded = true;
}
//DO OTHER STUFF
}
}
如果我执行一个名为
的方法,它就会起作用
public synchronized boolean getLoaded(){return loaded;}
但是为什么写和读过程必须同步?如果对象仅在写入时被锁定,那么读取必须等待,这还不够吗?在第一个示例中,我希望编程执行以下操作:
线程 A 正在读取加载的变量。
线程 B 想要写入加载的变量,但它是同步的,所以它锁定了对象。
线程 A 尝试读取加载的变量,但对象被锁定,因此它等待。
线程 B 写入变量。
线程 B 解锁。
线程 A 继续阅读。
我读了很多关于这个话题的书,但我不能 100% 理解它。希望有人能向我解释这个简单的项目。
你对synchronize的作用理解错误,它不是锁定你使用的对象,而是把那个对象当作信号量来锁定一段可执行代码。你的例子:
synchronized (this){
loaded = true;
}
只锁定一行"loaded = true"。它防止另一个线程可以输入同一行代码。它在 "synchronized(this)" 语句中等待,直到第一个线程(拥有信号量)通过释放信号量离开块。
你的问题更多的是一个线程如何等待和通知其他线程中的事件。有很多不同的技术可以做到这一点。现代的 (java8) 是使用 CompletableFuture。另一个更接近 java 的根源是 wait() 和 notify() 对,它们都是每个对象(及其派生对象)都知道的方法。我在 this SO answer
中提供了后者的一个简单示例
我无法理解 Java 中的 synchronized(){}。不知何故,我认为 synchronized(this) 我锁定了 Class 的 THIS 实例,如果我想访问一个属性或从另一个线程调用这个特定实例的函数,那么另一个线程必须等到 synchronized 结束。不知何故,在此示例代码中它不起作用。 我想让线程 A 等到线程 B 做某事后再继续。
public class A implements Runnable{
public void start(){
Thread t = new Thread(this);
t.start();
}
public void run(){
B b = new B();
b.start();
//DO STUFF
while(b.loaded){
//WAIT FOR B DOING STUFF
}
//GO ON DOING STUFF
}
}
public class B implements Runnable {
public boolean loaded;
public B(){
loaded = false;
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
public void run(){
//DOING STUFF
synchronized (this){
loaded = true;
}
//DO OTHER STUFF
}
}
如果我执行一个名为
的方法,它就会起作用public synchronized boolean getLoaded(){return loaded;}
但是为什么写和读过程必须同步?如果对象仅在写入时被锁定,那么读取必须等待,这还不够吗?在第一个示例中,我希望编程执行以下操作:
线程 A 正在读取加载的变量。
线程 B 想要写入加载的变量,但它是同步的,所以它锁定了对象。
线程 A 尝试读取加载的变量,但对象被锁定,因此它等待。
线程 B 写入变量。
线程 B 解锁。
线程 A 继续阅读。
我读了很多关于这个话题的书,但我不能 100% 理解它。希望有人能向我解释这个简单的项目。
你对synchronize的作用理解错误,它不是锁定你使用的对象,而是把那个对象当作信号量来锁定一段可执行代码。你的例子:
synchronized (this){
loaded = true;
}
只锁定一行"loaded = true"。它防止另一个线程可以输入同一行代码。它在 "synchronized(this)" 语句中等待,直到第一个线程(拥有信号量)通过释放信号量离开块。
你的问题更多的是一个线程如何等待和通知其他线程中的事件。有很多不同的技术可以做到这一点。现代的 (java8) 是使用 CompletableFuture。另一个更接近 java 的根源是 wait() 和 notify() 对,它们都是每个对象(及其派生对象)都知道的方法。我在 this SO answer
中提供了后者的一个简单示例