Java类中的单个静态字段
有一个类RedisLogger.java,用于处理带有redis的记录器。在RedisLogger.java中,我使用以下代码声明了一个静态JedisPool字段Java类中的单个静态字段,java,multithreading,static,synchronized,Java,Multithreading,Static,Synchronized,有一个类RedisLogger.java,用于处理带有redis的记录器。在RedisLogger.java中,我使用以下代码声明了一个静态JedisPool字段JedisPool: private static JedisPool jedisPool; 由于JedisPool是线程安全的CALS,我想使用以下代码在我的应用程序中仅实例化一次JedisPool: public static JedisPool getJedisPool() { if(jedisPool == null)
JedisPool
:
private static JedisPool jedisPool;
由于JedisPool是线程安全的CALS,我想使用以下代码在我的应用程序中仅实例化一次JedisPool
:
public static JedisPool getJedisPool() {
if(jedisPool == null) {
synchronized (JedisPool.class) {
if(jedisPool == null) {
jedisPool = new JedisPool();
}
}
}
return jedisPool;
}
我用这个代码来测试它
ExecutorService executor = Executors.newCachedThreadPool();
for(int i = 0; i < 1000; i++) {
executor.execute(()->{
System.out.println(RedisLogger.getJedisPool());
});
}
但它真的能达到我的期望吗?
因为在我的申请表中有很多类似的地方。比如说
private static Cluster getCluster() {
if(cluster == null) {
synchronized (Cluster.class) {
if(cluster == null) {
Builder builder = Cluster.builder();
for (int i = 0; i < MSConfig.SRCDOC_CASSANDRA_ADDRS().length; i++) {
builder.addContactPoint(MSConfig.SRCDOC_CASSANDRA_ADDRS()[i])
.withPort(MSConfig.SRCDOC_CASSANDRA_PORT()[i]);
}
cluster = builder.withCredentials(MSConfig.SRCDOC_CASSANDRA_USERNMAE(), MSConfig.SRCDOC_CASSANDRA_PASSWORD())
.withProtocolVersion(ProtocolVersion.V4)
.withPoolingOptions(getPoolingOptions())
.withSocketOptions(getSocketOptions())
.withRetryPolicy(getRetryPolicy())
.withQueryOptions(getQueryOptions())
.build();
}
}
}
return cluster;
}
private静态集群getCluster(){
if(cluster==null){
已同步(Cluster.class){
if(cluster==null){
Builder=Cluster.Builder();
对于(int i=0;i
谢谢 您可以直接为变量赋值,并在案例中声明它为
final static
我想到的唯一的增加是放弃同步化
初始化,直接使用。从:
JVM推迟初始化InstanceHolder类,直到它实际被使用为止,并且由于Singleton是用静态初始值设定项初始化的,不需要额外的同步
这可以在您的代码中使用,如下所示:
public class RedisLogger{
public static JedisPool getJedisPool(){
return JedisPoolHolder.INSTANCE;
}
private static final class JedisPoolHolder{
private static final JedisPool INSTANCE = new JedisPool();
}
// the rest of your code
}
您所做的工作称为“双重检查锁定”。如果你在Stackoverflow或Google上搜索这个,你会发现很多解释,解释为什么它在Java中不能正常工作 备选方案是:
为volatile
静态
是使某事物成为单一事物的关键字final
仅说明变量的值不能更改。因此,您目前的答案是错误的,它不一定是关于单例的,但是在这个上下文中final会很好,因为我们不想修改这个值,所以因为它将在声明期间赋值,所以它可以是final。虽然编辑了我的答案。但是你仍然需要static
一点误解。我的意思是在修改器中添加final,而不是用final替换它们。谢谢你的编辑。因为它是一个池,我想它会被修改。。。我不认为final
就在这里,但它真的能达到我的期望吗。应该这样。为什么不应该呢?你看到不一致吗?我们不知道您的代码,所以我们无法通过查看您的最后一个代码片段来判断它是否有效。我们需要完整的图片,但这会打破这个问题的框架。我知道,双重检查用于单例模式。但我想将其用于一个字段。您当前拥有的代码可能会泄漏未初始化的JedisPool
实例。这与单身汉无关。
public class RedisLogger{
public static JedisPool getJedisPool(){
return JedisPoolHolder.INSTANCE;
}
private static final class JedisPoolHolder{
private static final JedisPool INSTANCE = new JedisPool();
}
// the rest of your code
}