Java 变量的同步

Java 变量的同步,java,synchronization,synchronized,Java,Synchronization,Synchronized,在这个程序中,对象jai由一个线程访问,而它也由另一个线程修改。这是正确的工作方式吗?是否不需要使对象同步 public class SameObjectModification { private static int i = 0; private static Jai jai; static class Jai { private final int a; public Jai( int a ) { t

在这个程序中,对象
jai
由一个线程访问,而它也由另一个线程修改。这是正确的工作方式吗?是否不需要使对象同步

public class SameObjectModification {

    private static int i = 0;

    private static Jai jai;

    static class Jai {

        private final int a;

        public Jai( int a ) {
            this.a = a;
        }

        public void print() {
            System.out.println( "value ==> " + a );
        }
    }

    public static void main( String[] args ) {

        Thread t1 = new Thread() {

            @Override
            public void run() {
                while ( true ) {
                    if ( jai != null )
                        jai.print();
                }
            }
        };

        Thread t2 = new Thread() {

            @Override
            public void run() {
                while ( true ) {
                    jai = new Jai( i++ );
                }
            }
        };

        t1.start();
        t2.start();
    }
}

目前还不清楚您想要实现什么,但通过使用原子学,您可以为每个Jai获得唯一的a值

private static AtomicInteger i = new AtomicInteger(0);

private static Jai jai;

static class Jai {

    private int a;
    public Jai() {
        this.a = i.incrementAndGet();
    }

这是您的示例的thrade保存版本

private static int i = 0;

private static AtomicReference<Jai> jai = new AtomicReference<Jai>();

static class Jai {

    private final int a;

    public Jai( int a ) {
        this.a = a;
    }

    public void print() {
        System.out.println( "value ==> " + a );
    }
}

public static void main( String[] args ) {

    Thread t1 = new Thread() {

        @Override
        public void run() {
            while ( true ) {
                Jai tmp = jai.get();
                if ( tmp != null )
                    tmp.print();
            }
        }
    };

    Thread t2 = new Thread() {

        @Override
        public void run() {
            while ( true ) {
                jai.set(new Jai( i++ ));
            }
        }
    };

    t1.start();
    t2.start();
}
private static int i=0;
私有静态AtomicReference jai=新的AtomicReference();
静态类Jai{
私人终审法院;
公共监狱(内部a){
这个a=a;
}
公开作废印刷品(){
System.out.println(“值==>”+a);
}
}
公共静态void main(字符串[]args){
线程t1=新线程(){
@凌驾
公开募捐{
while(true){
Jai tmp=Jai.get();
如果(tmp!=null)
tmp.print();
}
}
};
线程t2=新线程(){
@凌驾
公开募捐{
while(true){
jai.set(新jai(i++));
}
}
};
t1.start();
t2.start();
}
但是实现取决于您的位置。 您应该仅对不可变或线程安全类使用AtomicReference

在其他情况下,您可以使用不同的锁、易失性字段、不同的原子实现(如AtomicLong)或同步


但是您应该记住,原子比锁快,锁比同步快。

事实上,变量
jai
按顺序引用许多对象。在第二个线程中循环的每次迭代中,将创建一个新对象并将其分配给变量。因此,在jai上同步不会有帮助

如果要确保
t2
线程创建的所有对象都由
t1
处理,则需要锁定t1并等待
t2
创建对象或使用某种队列。了解


更一般地说,这是一个问题的例子

你想达到什么目的?不,不是。您正在从不同的线程访问状态,而无需同步。所以你会有可见性问题。这取决于你想要什么。如果你想实现互斥,那么你必须对它进行同步。我想知道为什么我在运行这段代码时没有收到任何异常。你的代码不会收到任何异常,因为引用下的操作通常是CPU体系结构(如x86)的原子操作。但若你们在异国cpu上运行你们的代码,你们会得到异常。