我试图volatile
用一个例子来说明它的使用和重要性,如果volatile
省略的话,它实际上不会给出很好的结果。
但我并不习惯使用volatile
。下面的代码的想法是,如果volatile
省略则导致无限循环,如果存在则是完全线程安全的volatile
。以下代码是线程安全的吗?您是否还有其他使用的现实且简短的代码示例,如果没有该示例,volatile
将会给出明显不正确的结果?
这是代码:
public class VolatileTest implements Runnable {
private int count;
private volatile boolean stopped;
@Override
public void run() {
while (!stopped) {
count++;
}
System.out.println("Count 1 = " + count);
}
public void stopCounting() {
stopped = true;
}
public int getCount() {
if (!stopped) {
throw new IllegalStateException("not stopped yet.");
}
return count;
}
public static void main(String[] args) throws InterruptedException {
VolatileTest vt = new VolatileTest();
Thread t = new Thread(vt);
t.start();
Thread.sleep(1000L);
vt.stopCounting();
System.out.println("Count 2 = " + vt.getCount());
}
}
Victor是对的,您的代码存在问题:原子性和可见性。
这是我的版本:
private int count;
private volatile boolean stop;
private volatile boolean stopped;
@Override
public void run() {
while (!stop) {
count++; // the work
}
stopped = true;
System.out.println("Count 1 = " + count);
}
public void stopCounting() {
stop = true;
while(!stopped)
; //busy wait; ok in this example
}
public int getCount() {
if (!stopped) {
throw new IllegalStateException("not stopped yet.");
}
return count;
}
}
如果线程观察到stopped==true
,则可以确保工作完成并且结果可见。
从易失性写入到易失性读取(在同一变量上)之间存在事前关系,因此如果有两个线程
thread 1 thread 2
action A
|
volatile write
\
volatile read
|
action B
动作A在动作B之前发生;B中可以看到A中的写入。
我试图理解如果下面是线程安全的,它是由另一个开发人员编写的代码,我已经继承和不再与我们在一起。 我有一个BaseProvider类,它实际上是一个消息缓存,由LinkedBlockingQueue表示。该类将传入的消息存储在队列中。 我有一组读此队列的辅助线程。因此,LinkedBlockingQueue是线程安全的。 正如您所注意到的,每个辅助线程都可以访问所有的提供者,所以当一个辅助线程遍历所
问题内容: Java线程安全性易变吗?也就是说,可以安全地读取和写入它而无需锁定吗? 问题答案: 是的,您可以从中读取并安全地对其进行写入-但您不能做任何复合操作,例如安全地对其进行递增,因为这是一个读/修改/写周期。还有一个问题是它如何与 其他 变量的访问交互。 坦率地说,volatile的确切性质令人困惑(有关更多详细信息,请参见JLS的内存模型部分)-我 个人 通常会使用它作为确保正确使用的
问题内容: 很简单,可以从多个线程中使用一个实例(例如),还是需要将多个实例放在一个线程中? 问题答案: 不,不是。该实例是有状态的。因此,您需要将其存储在threadlocal中,或者在每次加密/解密调用中获取一个新实例,或者将其包装在一个块中。 Threadsafety通常在Javadoc中提到“ 是线程安全的 ”或“ 是 不是 线程安全的 ”。情况并非如此,因此您不应假定它是线程安全的。
类OneValueCache是不可变的。但是我们可以更改变量缓存的引用。 但我不能理解为什么VolateCachedFactorizer类是线程安全的。 对于两个线程(线程A和线程B),如果线程A和线程B同时到达,那么两个线程A和B都将尝试创建OnEvalueCache。然后线程A到达而线程B同时到达。然后线程A将创建一个,它覆盖threadB创建的值(OneValueChange是不可变的,但是
功能简介 一键报警 一键报警是在不方便语音通话的场景下,求助人无需进行复杂的信息编辑,可由平台提供更准确的实时定位信息、求助人和同车人信息和音视频信息供警方使用。 具体参见:一键报警 行程分享 行程分享是乘车人可以将当前行程分享到微信、短信、QQ、微博、钉钉等任意渠道中,让亲友随时关注行程信息。 具体参见:行程分享 紧急联系人 紧急联系人是乘车人在遇到紧急情况时向其发起帮助请求的人,设置后,可开启
volatile的写操作,无法保证线程安全。例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值,在线程1对count进行修改之后,会write到主内存中,主内存中的count变量就会变为6;线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6;导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。