• zero
    2019-05-11
    是有问题的,volatile关键字只能保证可见性,无法保证原子性和互斥性。所以calc方法有可能被重复执行。

    作者回复: 👍

    
     22
  • leon
    2019-05-14
    思考题代码相当于:
    if(intied == false) { // 1
         inited = true; //2
         count = calc()
    }

    可能有多条线程同时到1的位置,判断到inited为false,都进入2执行。
    解决方案:
    (1)加锁保护临界区
    (2) AtomicBoolean.compareAndSet(false, true)
    展开

    作者回复: 👍

    
     14
  • Corner
    2019-05-11
    最好就不要单独使用volatile防止产生线程安全问题。因为变量的读写是两个操作,和我们的直觉不一样,很容易出问题。老师的那个volatile就没有问题吗?如果一个线程修改了路由表,此时定时器任务判断共享变量为true,在将其修改为false之前,此时另一个线程又修改了路由表,然后定时任务继续执行会将其修改为false,这就出现问题了。最后还是要在autoSave方法上做同步的。

    作者回复: 定时器任务只有一个线程,autosave加不加同步就无所谓了,多保存一次也没关系,这种概率毕竟很小

    
     6
  • 郑晨Cc
    2019-05-11
    第8行 inited = true;改成cas操作
    失败直接return。成功继续执行cal方法
    
     4
  • 孙志强
    2019-05-14
    inited变量需要使用CAS的方式进行赋值,赋值失败就return,保证只有一个线程可以修改inited变量。

    作者回复: 👍

    
     3
  • 岥羽
    2019-08-07
    老师,自动保存路由表用 Balking 模式的volatile方式实现中,为什么对共享变量 changed 和 rt 的写操作不存在原子性的要求?
    
     2
  • Jxin
    2019-06-16
    volative修饰的属性。我见过在方法中。用局部变量接收该属性值,方法后续的操作都基于该局部变量。这样是不是就不再有volative的特性了?性能虽然提高了,毕竟能走缓存和编译优化了。但是就像上例双重检查的场景。这么个操作就依旧会有空指针异常的可能。请问老师我理解对吗。

    作者回复: 局部变量是不会在线程间共享的,也没有volatile特性

    
     2
  • 热台
    2019-05-11
    回答问题
    1,cal()可能被执行多次
    2. 也可能cal()执行结束前,count就被使用

    解决方法
    inited 赋值和cal()执行放在一个同步块中,并增加双重check
    展开

    作者回复: 👍

    
     1
  • 刘晓林
    2019-05-11
    有问题,存在竞态条件

    作者回复: 👍

    
     1
  • 锦
    2019-05-11
    回答问题:
    有问题,volatile不能保证原子性,题目要求只需计算一次Count,所以需要对共享变量inited加锁保护。

    疑问:
    public class RouterTable 类中AutoSave方法同一时刻只有一个线程调用,而Remove和Add方法也是要求使用方单线程访问吗?在实际开发中一般采用什么方式达成这种约定呢?

    作者回复: 你没有办法控制调用方的线程数,autosave你是能控制的。不过加锁以后就串行了

    
     1
  • 李湘河
    2019-11-24
    Volatile只能保证可见性,无法保证互斥性
    
    
  • DFighting
    2019-09-29
    volatile没办法保证操作的原子性,也就是在第一个线程执行inited=true时可能会发生时间片的切换,导致下一个线程在判断是否初始化的时候继续执行calc()操作,也就是说没办法保证calc()的唯一性,对比老师给的代码,应该为整个方法加上synchronized以达到只计算一次calc()的目的
    
    
  • 逆流的鱼
    2019-08-30
    这两个模式怎么这么违和,突兀,虎头虎脑的
    
    
  • 熊熊周周
    2019-06-21
    inited = true;
    除非代码所工作的操作系统平台环境或者java官方指定这个操作是原子性操作,线程安全的。我们不应该把它当做原子性的操作,线程安全性的操作。
    解决了原始数据类型赋值是否是原子性操作的疑问
     1
    
  • 奇奇
    2019-06-05
    课后思考题应该是!inited 代码是错的
    
    
  • points
    2019-05-31
    class Test{
        
        AtomicBoolean inited = new AtomicBoolean(false);
        
        void inited( ){
            if( inited.getAndSet(true) ){
                return ;
            }
            
        }
    }
    展开
    
    
  • Rancood
    2019-05-22
    这个Balking模式的好处就是将并发处理逻辑与业务逻辑分离吗
    
    
  • 贺宇
    2019-05-21
    这个问题好像和信号量那章的问题很相似
    
    
  • ZOU志伟
    2019-05-18
    竞态条件问题
    
    
  • gogo
    2019-05-16
    没有锁 有共享变量 多个线程 可能同时读到false哇, 就可能有多个线程init而让count值超过1哇。

    尽管读到了init=false, 真正的cal()也应该在同步里面,并且init此时任然是false哇~
    
    
我们在线,来聊聊吧