Discuss / Java / 如果多行赋值语句,就必须保证是同步操作!

如果多行赋值语句,就必须保证是同步操作!

Topic source

TommDooog

#1 Created at ... [Delete] [Delete and Lock User]

廖老师你好:

既然int类型赋值是原子性的,如下的代码为什么要同步呢?如果不同步,会出现什么后果?

class Pair {

    int first;

    int last;

    public void set(int first, int last) {

        synchronized(this) {

            this.first = first;

            this.last = last;

        }

    }

}

廖雪峰

#2 Created at ... [Delete] [Delete and Lock User]

你想把游戏里一个人从坐标(10,10)移动到(20,20),另一个线程把坐标准备移动到(30,30):

public void setPosition(int x, int y) {
    this.x = x;
    this.y = y;
}

最终结果要么是(20,20)要么是(30,30),

但是不同步的情况下,有可能出现(20, 30)或者(30,20)

这种是逻辑错误,不是你想要的最终结果

Joker.fu_95

#3 Created at ... [Delete] [Delete and Lock User]

多行操作不一定是同一个线程在处理

细水静流

#4 Created at ... [Delete] [Delete and Lock User]

如果不同步的话,那么可能线程1刚给x赋值完就被其他线程抢去然后对xy进行赋值,然后读写权交到线程1手上,这时线程1再对y写的时候其实x值已经被修改了。这只是其中一种情况,廖老师举了四种情况,同步的目的是为了保证一个线程可以对一组同时改变的数据完整读写后,再交给其他线程去做。再给你举个例子就是数据库中其实经常要涉及到原子性操作,就是为了保证这些语句都可以正确执行,你去存钱,要记录你的存钱金额,总金额,存款时间等,那么这些记录的插入都必须一起完成才行。

细水静流

#5 Created at ... [Delete] [Delete and Lock User]

另外忘了就是this.x,this.y 是共享变量是对多线程可见的,如果是局部变量其实就是只是把set()当做一个整体来看就行了。

这里的 x/y 应该都是static的吧,这样才是共享资源。 this的话,每个线程中都是new的话,那就不存在共享资源被修改不一致的情况了。


  • 1

Reply