在本文中,您将会了解到关于JavaWeb服务中的Singleton对象的新资讯,同时我们还将为您解释javaweb中service的相关在本文中,我们将带你探索JavaWeb服务中的Singleton
在本文中,您将会了解到关于Java Web服务中的Singleton对象的新资讯,同时我们还将为您解释javaweb中service的相关在本文中,我们将带你探索Java Web服务中的Singleton对象的奥秘,分析javaweb中service的特点,并给出一些关于android – 模块中的@Singleton和Dagger 2中的组件中的@Singleton之间的区别、asp.net – IIS Web Garden中的Singleton对象、ASP.NET(C#)Web服务中的异常处理、C#中的Singleton模式的实用技巧。
本文目录一览:- Java Web服务中的Singleton对象(javaweb中service)
- android – 模块中的@Singleton和Dagger 2中的组件中的@Singleton之间的区别
- asp.net – IIS Web Garden中的Singleton对象
- ASP.NET(C#)Web服务中的异常处理
- C#中的Singleton模式
Java Web服务中的Singleton对象(javaweb中service)
早上好,我目前正在开发一个公开Web服务接口的Java Web应用程序。为了将全局对象保留在内存中,我将以下类用作Singleton:
public class SingletonMap { private static final SingletonMap instance = new SingletonMap(); private static HashMap couponMap = null; private static long creationTime; private SingletonMap() { creationTime = System.currentTimeMillis(); couponMap = new HashMap(); } public static synchronized SingletonMap getInstance() { return instance; } public static long getCreationTime() { return creationTime; }}
我使用上面的类是为了使Web服务的所有线程都具有相同的HashMap实例。维护SingletonMap对象的Web服务类如下:
@WebService()public class ETL_WS { private String TOMCAT_TEMP_DIR; private final int BUFFER_SIZE = 10000000; private static SingletonMap couponMap; private static SingletonProductMap productCategoryMap; private String dbTable = "user_preferences"; public ETL_WS() { Context context = null; try { context = (Context) new InitialContext().lookup("java:comp/env"); this.TOMCAT_TEMP_DIR = (String) context.lookup("FILE_UPLOAD_TEMP_DIR"); }catch(NamingException e) { System.err.println(e.getMessage()); } public long getCouponMapCreationTime() { return couponMap.getCreationTime(); }}
我拥有方法getCouponMapCreationTime()的原因是要检查Web服务的所有线程是否正在访问同一对象。以上方法正确吗?性能开销如何?您是否认为我需要Singleton属性,或者是否可以对所有线程使用静态HashMap?如果我使用静态HashMap,如果没有线程处于活动状态,它将被垃圾回收吗?
感谢您的时间。
答案1
小编典典JAX-WS Web服务本身就是Singleton。这意味着将使用单个Web服务实例(如Servlet)处理所有请求。
因此,该类的任何成员将在所有请求之间“共享”。就您而言,您无需使成员(即couponMap)成为静态属性。
结论: 不用担心,您的所有线程(请求)都将访问相同的“
couponMap”。因为不再需要getCouponMapCreationTime
了,所以我认为您可以消除SingletonMap
抽象并直接在Web服务类中使用Map。
但是我要补充一些非常重要的内容。如果有多个线程(请求)将访问您的地图,则必须使其成为线程安全的!!!有很多方法可以做到这一点,但是我将给出一个想法:使用aConcurrentHashMap
代替a HashMap
。这将使您所有的get(), put(),remove()
操作都是线程安全的!如果需要更大的作用域,则可以使用同步块,但是请避免使用同步方法,因为瓢太大,并且始终在this
对象上进行同步。
android – 模块中的@Singleton和Dagger 2中的组件中的@Singleton之间的区别
我正在学习Dagger 2,我注意到在某些例子中,模块的方法中有@Singleton,而Component的方法上有其他的@Singleton?有什么区别以及模块方法和组件方法的@Singleton注释究竟是什么意思?
如果您还没有,请阅读User’s Guide以获取有关匕首和示波器的一些基本知识.
组件中的注释方法(提供方法)没有任何影响.您必须在模块中注释类或提供方法.我想快速展示你如何能够自己快速证明这一点:
我们有2个Component,一个使用范围@Singleton,另一个使用none:
@Singleton
@Component(modules = SingletonModule.class)
public interface SingletonComponent {
Object getobject();
}
@Component(modules = normalModule.class)
public interface normalComponent {
@Singleton
Object getobject();
}
这些组件有2个模块,一个提供单例范围对象(与组件相同),另一个只使用范围:
@Module
public class SingletonModule {
@Provides
@Singleton
public Object provideObject() {
return new Object();
}
}
@Module
public class normalModule {
@Provides
public Object provideObject() {
return new Object();
}
}
现在我们只是创建一个小测试:
public class ComponentTest {
@Test
public void testSingletonComponent() {
SingletonComponent component = DaggerSingletonComponent.create();
Assert.assertEquals(component.getobject(),component.getobject());
}
@Test
public void testnormalComponent() {
normalComponent component = DaggernormalComponent.create();
Assert.assertNotSame(component.getobject(),component.getobject());
}
}
此测试将成功并证明组件中的注释方法不起作用.在使用构造函数注入时,在模块中作用域对象或注释类本身将导致对象在同一作用域/同一组件中重用.
创建相同作用域的2个组件也会导致重复的对象,可以这样证明:
@Test
public void testTwoSingleonComponents() {
SingletonComponent component1 = DaggerSingletonComponent.create();
SingletonComponent component2 = DaggerSingletonComponent.create();
Assert.assertNotSame(component1.getobject(),component2.getobject());
}
一定要阅读一些教程,一定要尝试一下.如果你做错了,编译器会抱怨!
总结
以上是小编为你收集整理的android – 模块中的@Singleton和Dagger 2中的组件中的@Singleton之间的区别全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
asp.net – IIS Web Garden中的Singleton对象
CMIIW,使用n个工作进程移动到IIS Web Garden,将在每个工作进程中创建一个单独的对象,这使得它不再是单个对象,因为n> 1.
我可以在IIS Web Garden中再次制作所有这些单例对象吗?
解决方法
这是一个范围问题.您的单例实例使用进程空间作为其范围.就像你说的那样,你的实现现在跨越了多个进程. By definition,在大多数操作系统上,单例将绑定到某个进程空间,因为它与单个类实例或对象相关联.
你真的需要一个单身人士吗?在使用该模式之前,这是一个非常重要的问题.正如维基百科所说,有些人认为它是反模式(或代码气味等).
可能有效的替代设计示例包括……
>您可以让多个对象与中央存储或彼此同步.
>如果适用,请使用对象序列化.
>使用Windows服务和某种形式的IPC,例如. System.Runtime.Remoting.Channels.Ipc
我喜欢大型网站的选项3.对于大型网站,配套Windows服务通常非常有用.发送邮件,批处理作业等许多事情应该已经与前端处理工作进程分离.您可以将单例服务器对象推送到该进程,并在IIS工作进程中使用客户端对象.
如果您的单例类使用共享状态的多个对象或仅共享初始状态,则选项1和2应分别起作用.
编辑
从您的评论中,它听起来像分布式缓存形式的第一个选项应该适合您.
那里有很多分布式缓存实现.
> Microsoft AppFabric(以前称为VeLocity)是他们最近进入这一领域的举动.
> Memcached ASP.Net Provider
> NCache(MSDN Article ) – OutProc支持的自定义ASP.Net Cache提供程序.应该有其他自定义缓存提供程序.
>使用Windows服务和IPC推出自己的分布式缓存(选项3)
PS.因为你专门研究聊天.我肯定会建议研究Comet(Comet implementation for ASP.NET?和WebSync等)
ASP.NET(C#)Web服务中的异常处理
我所能找到的只是捕获从Web服务抛出到C#代码中的异常,但我从ajax代码而不是C#代码调用我的服务.我想要的不仅仅是返回的HTTP状态代码.
这是我的服务代码的catch块:
catch (Exception ex) { var fault = new GenericFault { Message = ex.Message,Operation = "" }; throw new FaultException<GenericFault>(fault); } }
这是我的ajax错误回调:
error: function (err) { alert("The server encountered an error,please resubmit your request. If the problem persists,contact your administrator."); return 'error occured'; }
我已经尝试过抛出Web故障异常,但这也没有达到目的,因为只有HTTP状态代码被传递.
解决方法
由于回调错误函数中捕获的错误会在xhr对象中看到详细信息.
所以你需要抛出HttpException传递它的状态代码和字符串消息.
catch块应该看起来像:
catch (Exception ex) { throw new HttpException(500,ex.Message); }
然后你的ajax回调将获得你从这里传递的ex.message:
error: function (err) { alert("The Detailed server error is "+err.responseJSON.Message); return 'error occured'; }
C#中的Singleton模式
前言
Singleton是二十三个设计模式中比较重要也比较经常使用的模式。但是这个模式虽然简单,实现起来也会有一些小坑,让我们一起来看看吧!
实现思路
首先我们看看这个设计模式的UML类图。
很清晰的可以看到,有三点是需要我们在实现这个模式的时候注意的地方。
- 私有化的构造器
- 全局唯一的静态实例
- 能够返回全局唯一静态实例的静态方法
其中,私有化构造器是防止外部用户创建新的实例而静态方法用于返回全局唯一的静态实例供用户使用。原理清楚了,接下来我们看看一些典型的实现方式和其中的暗坑。
实现方法
最简单的实现方法
最简单的实现方法自然就是按照UML类图直接写一个类,我们看看代码。
class Program
{
static void Main(string[] args)
{
var single1 = Singleton.Instance;
var single2 = Singleton.Instance;
Console.WriteLine(object.ReferenceEquals(single1, single2));
Console.ReadLine();
}
}
class Singleton
{
private static Singleton _Instance = null;
private Singleton()
{
Console.WriteLine("Created");
}
public static Singleton Instance
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
public void DumbMethod()
{
}
}
这段代码忠实的实现了UML类图里面的一切,查看输出结果,
如果多线程乱入?
现在我们给刚刚的例子加点调料,假设多个对实例的调用,并不是简单的,彬彬有礼的顺序关系,二是以多线程的方式调用,那么刚刚那种实现方法,还能从容应对吗?让我们试试。把Main函数里面的调用改成这样。
static void Main(string[] args)
{
int TOTAL = 10000;
Task[] tasks = new Task[TOTAL];
for (int i = 0; i < TOTAL; i++)
{
tasks[i] = Task.Factory.StartNew(() =>
{
Singleton.Instance.DumbMethod();
});
}
Task.WaitAll(tasks);
Console.ReadLine();
}
通过Factory创造出1万个Task,几乎同时去请求这个单例,看看输出。
咦,我们刚刚写的Singleton模式失效了,这个类被创造了5次(这段代码运行多次,这个数字不一定相同),一定是多线程搞的鬼,我们刚刚写的代码没有办法应对多线程,换句话说,是非线程安全的(thread-safe),那有没有办法来攻克这个难关呢?
线程安全的单例模式
Lock版本
提到线程安全,很多同学第一反应就是用lock,不错,lock是个可行的办法,让我们试试。添加一个引用类型的对象作为lock对象,修改代码如下(什么?你问我为什必须是引用类型的对象而不能是值类型的对象?因为lock的时候,如果对象是值类型,那么lock仅仅锁住了它的一个副本,另外一个线程可以畅通无阻的再次lock,这样lock就失去了阻塞线程的意义)
private static object _SyncObj = new object();
public static Singleton Instance
{
get
{
lock (_SyncObj)
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
}
运行一下,输出
只有一个实例创建,证明Lock起作用了,这个模式可行!不过有些不喜欢用Lock的同学可能要问,还有没有其他办法呢?答案是有的。
静态构造器版本
回想一下,C#中的类静态构造器,只会在这个类第一次被使用的时候调用一次,天然的线程安全,那我们试试不用Lock使用类静态构造器?修改Singleton类如下:
class Singleton
{
private static Singleton _Instance = null;
private Singleton()
{
Console.WriteLine("Created");
}
static Singleton()
{
_Instance = new Singleton();
}
public static Singleton Instance
{
get { return _Instance; }
}
public void DumbMethod()
{
}
}
去掉了Lock,添加了一个类静态构造器,试一试。
完美!对于不喜欢用Lock(在这个例子中,实例只会创建一次但是之后的所有线程都要先排队Lock再进入Critical code进行检查,效率比较低下)的同学,类静态构造器提供了一种很好的选择。
不过我们总是追求卓越。这个版本比Lock版本似乎更好一点,那还有没有更好的版本呢?有的。
Lazy版本
从net 4.0开始,C#开始支持延迟初始化,通过Lazy关键字,我们可以声明某个对象为仅仅当第一次使用的时候,再初始化,如果一直没有调用,那就不初始化,省去了一部分不必要的开销,提升了效率。如果你不熟悉Lazy或者想更多了解它,请参考。我们今天关注的重点在于,Lazy也是天生线程安全的,所以我们尝试用它来实现Singleton模式?修改代码如下:
class Singleton
{
private static Lazy<Singleton> _Instance = new Lazy<Singleton>(() => new Singleton());
private Singleton()
{
Console.WriteLine("Created");
}
public static Singleton Instance
{
get
{
return _Instance.Value;
}
}
public void DumbMethod()
{
}
}
输出结果中可以看到,我们达到了想要的效果:
在上面的代码中,私有变量_Instance现在是被声明为延迟初始化,这样不但天然实现了线程安全,同时在没有调用Instance静态方法的时候(也即没有调用_Instance.Value),初始化不会发生,这样就提高了效率。
总结
Singleton模式很常见,实现起来也很简单,只是要小心线程安全。以上三种方法都可以实现线程安全的Singleton模式。如果net 版本在4.0之上,建议使用Lazy版本,毕竟对比Lock版本,Lazy版本可以免去实现手动Lock之苦,对比Static版本,又有延迟初始化的性能优势,何乐而不为呢?
今天关于Java Web服务中的Singleton对象和javaweb中service的讲解已经结束,谢谢您的阅读,如果想了解更多关于android – 模块中的@Singleton和Dagger 2中的组件中的@Singleton之间的区别、asp.net – IIS Web Garden中的Singleton对象、ASP.NET(C#)Web服务中的异常处理、C#中的Singleton模式的相关知识,请在本站搜索。
本文标签: