什么是设计可能抛出异常的单例类的最佳方法?
在这里,我有一个Singleton(使用Bill Pugh的方法,在Wiki for Singleton中记录).
private static class SingletonObjectFactoryHolder{
//1
private static final ObjectFactory INSTANCE = new ObjectFactory();
}
private ObjectFactory() throws Exception{
//2
//create the factory
}
public static ObjectFactory getInstance(){
//3
return SingletonObjectFactoryHolder.INSTANCE;
}
Run Code Online (Sandbox Code Playgroud)
如果在2处抛出异常,我想将其传播给调用者.但是,我不能从第1行抛出异常.
那么,如果没有正确创建单例对象,我唯一的选择是返回一个空对象吗?
谢谢
PS我确实意识到如果它通过不同的类加载器加载或者如果反射性地加载,这个Singleton可能会破坏,但它对我的目的来说已经足够了.
// UPDATE
我很好奇,我可以不重新安排我的设计,如下所示抛出异常吗?
此外,我不需要任何同步(类加载器保证静态内部类只加载一次,并且仅在调用getInstance()时).因此,线程安全和懒惰实例化?
private static class SingletonObjectFactoryHolder{
//1
public static ObjectFactory getInstance() throws Exception{
return new ObjectFactory();
}
}
private ObjectFactory() throws Exception{
//2
//create the factory
}
public static ObjectFactory getInstance(){
//3
return SingletonObjectFactoryHolder.getInstance();
}
Run Code Online (Sandbox Code Playgroud)
再次感谢.
请稍微帮忙,考虑下面的代码.
public class Widget {
public synchronized void doSomething() {
...
}
}
public class LoggingWidget extends Widget {
public synchronized void doSomething() {
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
我读到当调用LoggingWidget中的doSomething()时,JVM将首先尝试获取LoggingWidget上的锁定,然后尝试获取Widget上的锁定.
我很想知道原因.是因为JVM知道doSomething()调用了super.doSomething(),或者因为调用子类方法也总是会获得对超类的锁定.
干杯
假设我有一个包装HashMap的类,如下所示:
public final class MyClass{
private final Map<String, String> map;
//Called by Thread1
public MyClass( int size ){
this.map = new HashMap<String, String>( size );
}
//Only ever called by Thread2
public final String put( String key, String val ){
return map.put( key, value );
}
//Only ever called by Thread2
public final String get( String key ){
return map.get( key );
}
//Only ever called by Thread2
public final void printMap( ){
//Format and print the contents of the …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading thread-safety happens-before
我已经阅读了第16.3节"初始化安全性"的一些解释 JCIP但仍然不清楚.该部分指出
"此外,任何可以通过正确构造的对象的最终字段(例如最终数组的元素或最终字段引用的HashMap的内容)到达的变量也可以保证对其他线程可见."
所以,如果我有以下可变对象:
public final class Container{
private String name;
private int cupsWon;
private double netWorth;
public Container( String name, int cupsWon, double netWorth ){
this.name = name;
this.cupsWon = cupsWon;
this.netWorth = netWorth;
}
//NO Setters
//Getters
}
Run Code Online (Sandbox Code Playgroud)
然后,线程1按如下方式创建它并将c传递给Thread2.
final Container c = new Container("Ted Dibiasi", 10, 1000000);
Run Code Online (Sandbox Code Playgroud)
Thread2(不是同时,假设在1 ms之后),读取c的值,是否有可能看到Thread2
c.name=null or
c.cupswon=0 or worst of all,
c.netWorth=0.0?
Run Code Online (Sandbox Code Playgroud)
干杯
我注意到有关吸气鬼的课程有些困惑.我正在更新源代码,希望这将是明确的.谢谢大家一起来看看.
public final class Container{
private String name;
private int cupsWon; …Run Code Online (Sandbox Code Playgroud) 我编写了一个 JMH 基准测试来比较 java 1.8 中 Avro (1.8.2) 和 Protobuf (3.5.0) 的序列化性能。根据 JMH 的说法,Protobuf 可以在一秒钟内序列化某些数据 470 万次,而 Avro 每秒只能序列化 800k 次。
序列化的测试数据约为 200 字节,我为 Avro 和 Protobuf 生成了架构。
这是我的 Avro 序列化代码,熟悉 Avro 的人可以确保我没有犯一些重大错误吗?
JMH 进行了基准测试,名为 Serialize 的方法。另外,我已将其发布在https://groups.google.com/forum/#!topic/protobuf/skmE78F-XbE
非常感谢
public final class AvroSerialization{
private BinartEncoder encoder;
private final SpecificDatumWriter writer;
public AvroSerialization( ){
this.writer = new SpecificDatumWriter( AvroGeneratedClass.class );
}
//MyDataObject = A pojo that contains the data to be serialized
public final byte[] serialize( MyDataObject data ){
ByteArrayOutputStream out …Run Code Online (Sandbox Code Playgroud) java serialization performance-testing protocol-buffers avro
有人可以验证我对构造函数执行后建立的内存栅栏的理解.例如,假设我有一个名为Stock的类.
public final class Stock{
private final String ticker;
private double qty;
private double price;
public Stock ( String ticker, double qty, double price ){
this.ticker = ticker;
this.qty = qty;
this.price = price;
//I am assuming a memory fence gets inserted here.
}
public final void updateQty( double qty ){
this.qty = qty;
}
public final void updatePrice( double price ){
this.price = price;
}
}
Run Code Online (Sandbox Code Playgroud)
此外,假设构造是由执行线程1,然后updateQty()和updatePrice()被称为若干时间线程2(总是由线程2).
我的论点是,在Thread1创建对象之后,对象的"可见性"与jvm中的所有其他线程建立.由于两个可变变量仅由Thread2更改,因此我不需要任何锁定.我对么?
我有一个名为SingletonController1的单例类.
这个SingletonController1实例化了一堆其他Singleton类.
SingletonController1{
Authenticator - Singleton;
DBAccessor - Singleton;
RiskAccessor - Singleton;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我将此设计重新设计为:
SingletonController2{
Authenticator -non-singleton;
DBAccessor -non-singleton;
RiskAccessor -non-singleton;
}
Run Code Online (Sandbox Code Playgroud)
只要SingletonController2是唯一一个实例化那三个非Singleton类的类,它在功能上是否与以前的设计相同?
干杯
我试图通过JMX启用我的核心Java应用程序以实现远程访问.但是,有两个限制使它变得比它应该更难.
a)我无权更改在linux机器上启动应用程序的脚本.因此,我无法将任何"jmxremote"参数传递给jvm.
b)com.sun.management.jmxremote.port = xxxx我指定的远程端口()很可能没有打开,我无法修改脚本来尝试另一个开放端口.我必须自动完成.
我试图通过编写一个类来解决这些限制,设置所有必需的jmxremote参数以及找到"免费"端口.
public class JmxRemoteConnectionHelper{
@Override
public void init( ) throws Exception{
InetAddress address = InetAddress.getLocalHost();
String ipAddress = address.getHostAddress();
String hostname = address.getHostName();
String port = String.valueOf( getFreePort( ) );
System.setProperty("java.rmi.server.hostname", ipAddress );
System.setProperty("com.sun.management.jmxremote", "true" );
System.setProperty("com.sun.management.jmxremote.authenticate", "false" );
System.setProperty("com.sun.management.jmxremote.ssl", "false" );
System.setProperty("com.sun.management.jmxremote.port", port );
}
private final int getFreePort( ){
**//seedPort is passed in the constructor**
int freePort = seedPort;
ServerSocket sSocket = null;
for( int i=ZERO; i<PORT_SCAN_COUNTER; i++ ){
try{
freePort …Run Code Online (Sandbox Code Playgroud) 我试图以一种对Java无锁程序员有用的级别来理解内存障碍,我觉得这个级别介于学习volatile和根据x86手册学习存储/加载缓冲区之间。
我花了一些时间阅读一堆博客/食谱,并提出了以下摘要。知识渊博的人可以看一下摘要,看看我是否错过或列出了不正确的内容。
围栏:
Name : LFENCE/Load Barrier/Acquire Fence
Barriers : LoadLoad + LoadStore
Details : Given sequence {Load1, LFENCE, Load2, Store1}, the
barrier ensures that Load1 can't be moved south and
Load2 and Store1 can't be moved north of the
barrier.
Note that Load2 and Store1 can still be reordered.
Buffer Effect : Causes the contents of the LoadBuffer
(pending loads) to be processed for that CPU.This
makes program state exposed from other CPUs visible
to this CPU before Load2 …Run Code Online (Sandbox Code Playgroud) 我有一个独立的 java 应用程序,它使用 Hikaricp 获取消息流、批量并将它们插入到 SQL Server 数据库中。
目前我所做的事情如下:
请注意,我从不关闭连接!一旦达到 maxPoolSize (20),当我尝试获取新连接时会收到错误消息。
我应该在每次批量插入后关闭连接吗?
但是,这意味着我要承担从池中获取连接+在每次批量插入后创建新的准备好的语句的成本。
这是推荐的方法还是有任何替代方法可以减少这种额外成本?
java ×10
concurrency ×4
singleton ×2
avro ×1
constructor ×1
exception ×1
hikaricp ×1
jdbc ×1
jmx ×1
locking ×1
memory ×1
reentrancy ×1
spring-jmx ×1
volatile ×1
x86 ×1