哎呀好气啊
2017-12-20 03:14
采纳率: 0%
浏览 3.4k

假设test类运行于多线程环境下,那么关于A处的同步下面描述正确的是,求详细的解释

 public class Test {
  List list= new java.util.ArrayList();
  public void test() {
    synchronized ( list) { // --A
      list.add( String.valueOf(System.currentTimeMillis()));
    }
  }
}

A. test方法中必须增加synchronized
B. Test类为singleton时有必要增加synchronized
C. test方法中没有必要增加synchronized
D. Test类为singleton时也没有必要增加synchronized

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

9条回答 默认 最新

  • ipple1986 2017-12-20 05:59

    答案就是B
    A 如果Test类不是单例的话,那么list就是多个Test类里的多个实例list,所以加不加synchronized都是非线程安全的
    B 对的,单例Test时,保证list也是唯一的实例对象,多线程访问test方法时,共同抢夺list这把对象监视锁。
    C 与A解释相似,有没有必要看是否Test类是否单例
    D 单例时,必要加上synchronized才能保证线程安全性。

    点赞 4 打赏 评论
  • blownewbee 2017-12-20 03:20

    A. test方法中必须增加synchronized
    因为add操作不是线程安全的(不是原子化的),必须同步
    c不用解释了。
    和singleton没有关系。singleton只能保证私有成员是唯一的,不能保证线程安全。

    点赞 打赏 评论
  • 懒惰的毛毛虫 2017-12-20 03:31

    首先楼主需要理解 类锁 和 实例锁
    类锁:所有实例共享的锁 所有的实例 共享一把锁 ,
    实例锁 :每个实例自己的锁 不同实例之间不影响
    而楼主上面的 synchronized ( list) 就是对list这个实例加锁 是一个实例锁 所有对list这个实例的操作都需要获取锁
    然后除非一个对象本身是线程安全的,不然对这个对象的操作都需要加锁 list就是非线程安全的
    下面我们来分析答案:

    首先我们排除答案c 不加锁的话 肯定是非线程安全的
    当test为单例,言下之意就是list也是单例的 但是list是非线程安全的 所以必须加锁
    当test为非单例,也就是说list为非单例,当多个线程对同一个test类的list进行操作 此时还是需要加锁
    综上:答案A正确

    点赞 打赏 评论
  • ZhihengTao 2017-12-20 05:12

    你的问题关键在两点,同步synchronized和单例singleton

    先说同步synchronized
    同步其意义是为了确保动作的原子性(即动作一旦开始,不会被中途打断).
    所以,它的存在就是为了解决动作可能被打断(多线程),但为了程序正确性某些动作不能被打断的问题
    具体到程序,某段逻辑可能被多线程执行,但某次执行不应该被中断,否则会出错时,就需要对其加锁(如本例中synchronized)

    再说单例singleton
    单例其意义是为了确保某个类只能创建唯一对象(例如:你有一个数据库连接类,不需要同时存在多个连接,就可以使用单例)
    换言之,同一个单例类使用的实例,无论在哪里,都是同一个

    所以,这个问题的答案应该可以想清楚了吧

    点赞 打赏 评论
  • 他们叫我悟空 2017-12-20 07:26

    在你查询的地方,进行转换, 正常,异常,,,数据库存的是0,1代号, 转换成相应数字在查询就可以了。

    点赞 打赏 评论
  • 逗比123号 2017-12-20 07:39

    CD不用想。B是正确的,但是A有一个问题,多线程操作同一个test(),那么要加synchronized。但是多线程操作不同的test()方法,那么就不用增加synchronized了

    点赞 打赏 评论
  • yuyubingMan 2017-12-20 14:31

    题意的关键是要保护ArrayList,该集合本身是非线程安全的。
    然后要区分是类锁还是实例锁。简单来说锁的对象带了static关键字的就是类锁,没带就是实例锁;
    比如说加在静态方法上的就是类锁,对所有实例有效,实例锁只对当前对象有效。就是作用范围不一样。

    回到题目:如果是多个线程访问该类,但是为每个线程单独生成了实例,就像struts2 的Action,那么就无需加锁;
    如果多个线程访问同一个Test类生成的实例,那么就需要保护。

    点赞 打赏 评论
  • qq_35384834 2017-12-30 12:34

    我选择的答案是B
    理由是:
    当test类是多个实例的时候,Test类的list属性为各自每个Test类的,
    把线程比喻做人,test类的list属性当做锁,实现的方法当做是test方法相当于关上门睡觉
    当有二个线程访问时候,因为每个Test类都有各自的list属性,就相当二个人有各自的钥匙去自己的房间睡觉,此时并没有线程冲突问题

    当Test类是单利的时候,list属性就是唯一的,相当于你们家卫生间的门,二个线程访问时候,就类似二个人为争夺卫生间使用权,争取到的人就可以到卫生间关上门上述锁 使用,只有当使用完卫生间的锁才会开,另一个人才可以去使用,此时就有线程安全的问题,就需要锁了

    以上分析,选B

    点赞 打赏 评论
  • ipple1986 2020-12-11 16:04

    b

    点赞 打赏 评论

相关推荐 更多相似问题