![]() |
1
16
不,不是。你没有申报
这里是 Singleton 成语:
应该是
如果加载很昂贵,因此您更喜欢单例加载的延迟,那么考虑 Singleton holder 按需初始化而不是在类加载期间初始化的习惯用法:
不过,你应该在是否需要 独生子女 或者没有。通常不需要。 只是 静态变量、枚举、工厂类和/或依赖注入通常是更好的选择。 |
![]() |
2
13
还有一种方法:
根据Josh Bloch的有效Java,这是在Java中实现Simelton的最好方法。与涉及私有静态实例字段的实现不同,该实例字段可以通过滥用反射和/或序列化进行多次实例化,枚举保证为单例。 枚举单例的主要限制是它们总是在类加载时被实例化,并且不能被延迟地实例化。因此,例如,如果您想使用运行时参数实例化一个单例,那么您必须使用不同的实现(最好使用双重检查锁定)。 |
![]() |
3
2
我就是这样做的。它更快,因为它只需要
|
![]() |
4
1
使用您的示例并使用GOF的实现方法:
希望这有助于: |
![]() |
5
1
在Java中创建单体有3种方法。
|
![]() |
6
1
您的类(原始代码,编辑前):
不是真正的单身汉:
仍然有
|
![]() |
7
1
|
![]() |
8
0
在这一点上,可能有点晚了,但是一个基本的实现看起来是这样的:
这里我们有mysingleton类,它有一个名为instance的私有静态成员,以及一个名为getInstance()的公共静态方法。第一次调用getInstance()时,实例成员为空。然后流将进入创建条件,并创建mysingleton类的新实例。对getInstance()的后续调用将发现实例变量已设置,因此不会创建另一个mysingleton实例。这样可以确保只有一个mysingleton实例在getInstance()的所有调用方之间共享。 但是这个实现有一个问题。多线程应用程序在创建单个实例时将具有竞争条件。如果多个执行线程同时(或大约)命中getInstance()方法,它们将每个线程都将实例成员视为空。这将导致每个线程创建一个新的mysingleton实例,然后设置实例成员。
这里我们使用方法签名中的synchronized关键字来同步getInstance()方法。这肯定会改善我们的比赛条件。线程现在将一次阻塞并输入一个方法。但它也会造成性能问题。此实现不仅同步单个实例的创建,还同步对getInstance()的所有调用,包括读取。读取不需要同步,因为它们只返回实例的值。因为reads将占我们调用的大部分(记住,实例化只在第一个调用上发生),所以通过同步整个方法,我们将导致不必要的性能损失。
在这里,我们将同步从方法签名移到了包装mysingleton实例创建的同步块。但这能解决我们的问题吗?好吧,我们不再阻止读取,但我们也后退了一步。多个线程将同时或大约同时命中getInstance()方法,它们都将实例成员视为空。然后,它们将命中同步块,其中一个将获取锁并创建实例。当该线程退出该块时,其他线程将争夺该锁,并且每个线程将逐个通过该块并创建我们类的新实例。所以我们就回到开始的地方。
在这里,我们从街区内再开出一张支票。如果已经设置了实例成员,我们将跳过初始化。这叫做双重检查锁定。 这就解决了多重实例化的问题。但我们的解决方案再一次提出了另一个挑战。其他线程可能不_请参见已更新实例成员的__。这是因为Java如何优化内存操作。线程将变量的原始值从主内存复制到CPU的缓存中。然后,对值的更改将写入该缓存并从中读取。这是为优化性能而设计的Java特性。但这给我们的单例实现带来了一个问题。第二个线程___由不同的CPU或内核处理,使用不同的缓存_____,将看不到第一个线程所做的更改。这将导致第二个线程将实例成员视为空,从而强制创建singleton的新实例。
我们通过在实例成员的声明中使用volatile关键字来解决这个问题。这将告诉编译器始终读取和写入主内存,而不是CPU缓存。 但这种简单的改变是有代价的。因为我们绕过了CPU缓存,所以每次对易失性实例成员_____进行操作时,我们都会受到性能影响,我们会进行4次操作。我们再次检查是否存在(1和2),设置值(3),然后返回值(4)。有人可能会说,这条路径是边缘情况,因为我们只在方法的第一次调用期间创建实例。也许对创作的影响是可以容忍的。但即使我们的主要用例reads也会对易失性成员进行两次操作。一次检查是否存在,然后再次返回其值。
由于性能下降是由于直接在易失性成员上操作造成的,因此,让_s将局部变量设置为易失性的值,并改为在局部变量上操作。这将减少我们在易失性上操作的次数,从而恢复一些丢失的性能。请注意,当我们进入同步块时,必须再次设置本地变量。这样可以确保它是最新的,并且在等待锁时发生了任何更改。 我最近写了一篇关于这个的文章。 Deconstructing The Singleton . 您可以在这里找到关于这些示例和“holder”模式的示例的更多信息。还有一个真实的例子展示了双重检查的易失性方法。希望这有帮助。 |
![]() |
9
0
singloton类是每次获取相同对象的类。 当您想限制一个类创建多个对象时,我们需要单例类。 例如:
要创建此类的对象,我们可以使用:
|
![]() |
10
0
创建singleton类时,应该考虑以下属性
如果类中没有克隆或序列化接口,我认为下面的类最好是单例类。
|
|
user29759326 · 如何返回递归函数中的最后一个值? 3 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 3 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 3 月前 |
![]() |
rudraraj · java中未声明最终变量 3 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 4 月前 |