java并发编程小案例(六)

在Java并发编程中,仅对写方法加锁可能无法完全避免数据不一致。当一个线程修改共享数据后,其他线程通过非同步的读方法可能会读到未完整更新的数据,即出现脏读。示例中,即使set方法同步,getAccount方法如果不加锁,仍可能出现脏读问题。解决方案取决于业务需求,如允许脏读则无需改动,否则需将getAccount方法也设置为同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class Test6 {
    private double account;
    private String name;

    public synchronized void set(double account , String name){
        this.name = name;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.account = account;
    }

    public double getAccount(){
        return this.account;
    }

    public static void main(String[] args) {
        Test6 t = new Test6();
        new Thread(()->t.set(100.0,"abc")).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(t.getAccount());

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(t.getAccount());
    }

}

问1:加锁只对写方法加锁就万无一失了吗?
上述代码对set方法设置为同步,指的是某个线程执行set方法时,其他线程不能再同时执行set方法了。 set方法中的睡2秒钟是放大了线程执行时的时间差,为了让问题更突显而已。
尽管在set方法设置为同步,但共享的数据可能被非同步方法访问到。当new的线程执行完 this.name = name 后 , 此时主线程去调用 t.getAccount(),那么拿到的结果是还未设置account的值;等 new的线程 执行完 this.account = account后,此时主线程再去调用t.getAccount(),就会拿到新的值。产生脏读。(读到了还没有写完的数据)

解决:看具体业务需要
如果允许脏读,就不管了。
如果不允许脏读,则将getAccount 设置为 synchronized

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值