如题,开发中遇到一个棘手的问题:
如果在一个类调用其父类super构造函数之前对它的非静态字段赋值,并且对这个字段上锁,锁实际上处于一种量子叠加态(有的时候能锁住,有的时候即使锁了也能被其他线程访问),这对需要严格禁止多线程访问的对象而言是不可接受的。
目前用了一个卑劣的hack,即让所有对象都只能被同步创建,然后全部都锁死静态字段来保证不会使得不允许多线程访问的对象被多个线程同时访问:
这个问题复现其实不难,在super构造函数被调用之前,先用synchronized锁住一个字段,然后再synchronized代码块中把它赋值给另一个线程上的一个静态字段,你会发现你有时候能成功地同时在两个线程上面访问这个对象。在一些测试中发现,貌似不同的JVM实现和JIT实现还会对结果产生影响,如果在INVOKESPECIAL指令执行完毕之后再锁住,几乎所有的JVM实现和JIT实现上都不会发生synchronized失效的问题。
求大神解答,感谢!
如果在一个类调用其父类super构造函数之前对它的非静态字段赋值,并且对这个字段上锁,锁实际上处于一种量子叠加态(有的时候能锁住,有的时候即使锁了也能被其他线程访问),这对需要严格禁止多线程访问的对象而言是不可接受的。
目前用了一个卑劣的hack,即让所有对象都只能被同步创建,然后全部都锁死静态字段来保证不会使得不允许多线程访问的对象被多个线程同时访问:
这个问题复现其实不难,在super构造函数被调用之前,先用synchronized锁住一个字段,然后再synchronized代码块中把它赋值给另一个线程上的一个静态字段,你会发现你有时候能成功地同时在两个线程上面访问这个对象。在一些测试中发现,貌似不同的JVM实现和JIT实现还会对结果产生影响,如果在INVOKESPECIAL指令执行完毕之后再锁住,几乎所有的JVM实现和JIT实现上都不会发生synchronized失效的问题。
求大神解答,感谢!