英文:
Is it possible to read stale value of non-volatile variable during read from another thread?
问题
以下是您提供的内容的中文翻译:
我有一个主线程,它构造了一个带有非volatile变量的对象,然后在此线程中我改变了变量的值,并将对象放入BlockingQueue中。
在第二个线程中,我等待直到对象可用,然后读取对象及其变量。
示例代码:
public class ReadCheck {
static BlockingQueue<A> queue = new LinkedBlockingQueue<>();
public static class A {
public int a;
public A(int a) {
this.a = a;
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
A a = queue.take();
if (a.a != 20) {
System.out.println(a.a);
}
} catch (InterruptedException e) {
}
}
}
}).start();
while (true) {
A a = new A(10);
a.a = 20;
queue.offer(a);
}
}
}
在示例运行期间,我从未看到变量为10(它总是20)。
在这种情况下,我是否可能读取了过期的变量值(10)?
这段代码示例是线程安全的吗?
英文:
I have a main thread which constructs an object with a non-volatile variable and then in this thread I change the value of the variable and put the object to BlockingQueue.
In second thread I wait until the object be available and read the object and its variable.
Example code:
public class ReadCheck {
static BlockingQueue<A> queue = new LinkedBlockingQueue<>();
public static class A {
public int a;
public A(int a) {
this.a = a;
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
A a = queue.take();
if (a.a != 20) {
System.out.println(a.a);
}
} catch (InterruptedException e) {
}
}
}
}).start();
while (true) {
A a = new A(10);
a.a = 20;
queue.offer(a);
}
}
}
During run of example I've never seen that variable is 10 (it's always 20).
Is it possible that I read stale value (10) of variable in second thread in such case?
Is this code example thread safe?
答案1
得分: 2
不可以,你无法读取过期的值;是的,它将保证线程安全。
阻塞队列的保证是offer
操作发生在take
操作之前,所以对A.a
中的值的写操作将在你读取它之前发生。
> 与其他并发集合一样,在将对象放入阻塞队列之前的线程操作先于在另一个线程中访问或删除该元素之后的操作。
英文:
No, you can't read a stale value; yes, it will be thread safe.
The blocking queue guarantees that offer happens before take, so the write to the value in A.a
will happen before you read it.
> As with other concurrent collections, actions in a thread prior to placing an object into a BlockingQueue happen-before actions subsequent to the access or removal of that element from the BlockingQueue in another thread.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论