线程安全单例类

我写了下面的Singleton类。我不确定这是否是线程安全的单例类吗?


public class CassandraAstyanaxConnection {


    private static CassandraAstyanaxConnection _instance;

    private AstyanaxContext<Keyspace> context;

    private Keyspace keyspace;

    private ColumnFamily<String, String> emp_cf;




    public static synchronized CassandraAstyanaxConnection getInstance() {

        if (_instance == null) {

            _instance = new CassandraAstyanaxConnection();

        }

        return _instance;

    }


    /**

     * Creating Cassandra connection using Astyanax client

     *

     */

    private CassandraAstyanaxConnection() {


        context = new AstyanaxContext.Builder()

        .forCluster(ModelConstants.CLUSTER)

        .forKeyspace(ModelConstants.KEYSPACE)

        .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      

            .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)

        )

        .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")

            .setPort(9160)

            .setMaxConnsPerHost(1)

            .setSeeds("127.0.0.1:9160")

        )

        .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      

            .setCqlVersion("3.0.0")

            .setTargetCassandraVersion("1.2"))

        .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())

        .buildKeyspace(ThriftFamilyFactory.getInstance());


        context.start();

        keyspace = context.getEntity();


        emp_cf = ColumnFamily.newColumnFamily(

            ModelConstants.COLUMN_FAMILY, 

            StringSerializer.get(), 

            StringSerializer.get());

    }


    /**

     * returns the keyspace

     * 

     * @return

     */

    public Keyspace getKeyspace() {

        return keyspace;

    }


    public ColumnFamily<String, String> getEmp_cf() {

        return emp_cf;

    }

}

谁能帮我这个?我在上述Singleton课堂上的任何想法都会有很大帮助。

谁能看一下,让我知道这次是否正确?

谢谢您的帮助。




幕布斯7119047
浏览 342回答 3
3回答

智慧大石

您正在实现惰性初始化模式-首次使用实例时在其中创建实例。但是有一个简单的技巧,可以让你的代码,一个线程的实现并不需要同步!它称为“ 按需初始化持有人”习惯用法,它看起来像这样:public class CassandraAstyanaxConnection {&nbsp; &nbsp; private CassandraAstyanaxConnection(){ }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; private static class Holder {&nbsp; &nbsp; &nbsp; &nbsp;private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();&nbsp; &nbsp; }&nbsp; &nbsp; public static CassandraAstyanaxConnection getInstance() {&nbsp; &nbsp; &nbsp; &nbsp; return Holder.INSTANCE;&nbsp; &nbsp; }&nbsp; &nbsp; // rest of class omitted}此代码在首次调用时初始化实例getInstance(),并且重要的是由于类加载器的约定,不需要同步:类加载器在首次访问类时加载类(在这种情况下Holder,唯一的访问是在getInstance()方法内)当加载了一个类,并且在任何人都可以使用它之前,请确保所有静态初始化程序都将被执行(这是在Holder静态块触发时)类加载器内置了自己的同步功能,可以确保上述两点是线程安全的每当需要懒惰初始化时,我都会使用这巧妙的小技巧。final即使实例是惰性创建的,您也可以获得实例的奖励。还要注意代码是多么干净和简单。编辑:您应该将所有构造函数设置为私有或受保护。设置并清空私有构造函数即可完成工作

潇潇雨雨

以上所有方法都急于初始化对象。这个怎么样。这将帮助您懒惰地初始化ur类。您可能有重物,并且不想在启动时进行初始化。public class MySinglton {&nbsp;&nbsp; private MySinglton (){}&nbsp; private static volatile MySinglton s;&nbsp; public static MySinglton getInstance(){&nbsp; &nbsp;if (s != null ) return s;&nbsp; &nbsp; synchronized(MySinglton.class){&nbsp; &nbsp; &nbsp;if (s == null ) {&nbsp; &nbsp; &nbsp; s = new MySinglton();&nbsp; &nbsp; &nbsp;}&nbsp; }&nbsp; return s;}}&nbsp;

慕勒3428872

不,如果在pulbic方法上返回的值是可更改的对象,则它不是线程安全的。对于此类,线程安全的一种方法是将其更改为不可变的。为此,您可以这样更改此方法:public Keyspace getKeyspace() {&nbsp; &nbsp; // make a copy to prevent external user to modified or ensure that Keyspace is immutable, in that case, you don't have to make a copy&nbsp; &nbsp; return new Keyspace( keyspace );}public ColumnFamily<String, String> getEmp_cf() {&nbsp; &nbsp; // Same principle here. If ColumnFamily is immutable, you don't have to make a copy. If its not, then make a copy&nbsp; &nbsp; return new ColumnFamily( emp_cf );}在本书《Java并发实践》中,您可以了解这种不变性的原理。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java