Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在不同步的情况下使用volatile_Java_Volatile - Fatal编程技术网

Java 在不同步的情况下使用volatile

Java 在不同步的情况下使用volatile,java,volatile,Java,Volatile,知道 读写是针对所有声明为volatile的变量的 问题1:这是否可以理解为 private volatile int x = 0; x++操作是原子的 那 标记变量volatile并不能消除同步的所有需要 原子行动,因为 问题2:我想知道在什么情况下(如果有的话),可以看到标记为volatile的变量,而看不到标记为synchronized的块的任何方法(尝试访问/修改变量) 换言之,所有需要防止并发修改的变量是否应标记为volatile x++;操作是原子的 否。这将减少到x=x+1。对x

知道

读写是针对所有声明为volatile的变量的

问题1:这是否可以理解为

private volatile int x = 0;
x++操作是原子的

标记变量volatile并不能消除同步的所有需要 原子行动,因为

问题2:我想知道在什么情况下(如果有的话),可以看到标记为
volatile
的变量,而看不到标记为synchronized的块的任何方法(尝试访问/修改变量)

换言之,所有需要防止并发修改的变量是否应标记为
volatile

x++;操作是原子的

否。这将减少到
x=x+1
。对
x
的读取是原子的,对
x
的写入是原子的,但是
x=x+1
作为一个整体不是原子的

我想知道在什么情况下(如果有的话),可以看到标记为volatile的变量,而看不到标记为synchronized的块的任何方法(尝试访问/修改变量)


嗯,有各种并发方法都不使用
synchronized
。Java中还有各种各样的其他锁定实用程序,无锁算法仍然需要像
volatile
这样的东西:
ConcurrentLinkedQueue
是一个具体的例子,尽管它广泛使用了“magic”
compareAndSet
原子。

否同步(尽管可以从volatile-开始构建同步块) 因此,不,它对
x++
没有帮助-这仍然是一种读写操作,需要某种形式的同步

volatile的一个例子是著名的双重检查锁定,在这种锁定中,我们大部分时间都避免同步,因为我们只需要排序保证:

private volatile Helper helper = null;
public Helper getHelper() {
    if (helper == null) {
        synchronized(this) {
            if (helper == null) {
                helper = new Helper();
            }
        }
    }
    return helper;
}
一个绝对不涉及同步的示例是一个简单的退出标志,这里它不是关于排序保证,而是关于保证的可见性

public volatile boolean exit = false;
public void run() {
   while (!exit) doStuff();
   // exit when exit set to true
}

如果另一个线程设置了
exit=true
,则执行while循环的另一个线程保证可以看到更新-如果没有volatile,则可能看不到更新

作为一个可快速测试的示例,可以说明前面的答案,这始终会产生8的最终计数:

import java.util.concurrent.atomic.AtomicInteger;


public class ThreadTest_synchronize {

public static void main(String[] args) {

    ThreadTest_synchronize tt = new ThreadTest_synchronize ();
    try {
        tt.go();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

private void go() throws InterruptedException{

    MyRunnable t = new MyRunnable();
    Thread myThread_1 = new Thread( t, "t1");
    Thread myThread_2 = new Thread( t, "t2");
    myThread_1.start();
    myThread_2.start();
    myThread_1.join();
    myThread_2.join();
    System.out.println("Processing count="+t.getCount());       

}

private class MyRunnable implements Runnable{

    private AtomicInteger count=new AtomicInteger(0);

    @Override
    public  void run() {
        for(int i=1; i< 5; i++){
            doSomething(i);
            count.getAndAdd(1);
        }           
    }


    public AtomicInteger getCount() {
        return this.count;
    }


    private void doSomething(int i) {
        try {
            Thread.sleep(i*300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}       

}
导入java.util.concurrent.AtomicInteger;
公共类线程测试\u同步{
公共静态void main(字符串[]args){
ThreadTest_synchronize tt=新的ThreadTest_synchronize();
试一试{
tt.go();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
private void go()引发InterruptedException{
MyRunnable t=新的MyRunnable();
线程myThread_1=新线程(t,“t1”);
螺纹myThread_2=新螺纹(t,“t2”);
myThread_1.start();
myThread_2.start();
myThread_1.join();
myThread_2.join();
System.out.println(“Processing count=“+t.getCount());
}
私有类MyRunnable实现Runnable{
私有AtomicInteger计数=新的AtomicInteger(0);
@凌驾
公开募捐{
对于(int i=1;i<5;i++){
剂量测定法(i);
计数。getandad(1);
}           
}
公共原子整数getCount(){
返回这个.count;
}
私人无效剂量测定(int i){
试一试{
睡眠(i*300);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}       
}
但这通常不会:

public class ThreadTest_volatile {

public static void main(String[] args) {

    ThreadTest_volatile tt = new ThreadTest_volatile ();
    try {
        tt.go();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

private void go() throws InterruptedException{

    MyRunnable t = new MyRunnable();
    Thread myThread_1 = new Thread( t, "t1");
    Thread myThread_2 = new Thread( t, "t2");
    myThread_1.start();
    myThread_2.start();
    myThread_1.join();
    myThread_2.join();
    System.out.println("Processing count="+t.getCount());       

}

private class MyRunnable implements Runnable{

    private volatile int count = 0;


    @Override
    public  void run() {
        for(int i=1; i< 5; i++){
            doSomething(i);
            count++;
        }

    }

    private  int add(int count){
        return ++count;
    }


    public int getCount(){
        return count;
    }

    private void doSomething(int i) {

        try {
            Thread.sleep(i*300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


}
公共类ThreadTest\u volatile{
公共静态void main(字符串[]args){
ThreadTest_volatile tt=新的ThreadTest_volatile();
试一试{
tt.go();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
private void go()引发InterruptedException{
MyRunnable t=新的MyRunnable();
线程myThread_1=新线程(t,“t1”);
螺纹myThread_2=新螺纹(t,“t2”);
myThread_1.start();
myThread_2.start();
myThread_1.join();
myThread_2.join();
System.out.println(“Processing count=“+t.getCount());
}
私有类MyRunnable实现Runnable{
私有易失性整数计数=0;
@凌驾
公开募捐{
对于(int i=1;i<5;i++){
剂量测定法(i);
计数++;
}
}
专用整数相加(整数计数){
返回++计数;
}
public int getCount(){
返回计数;
}
私人无效剂量测定(int i){
试一试{
睡眠(i*300);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}

极好的答案和示例。非常感谢。