Eclipse RAP 多客户端但单服务器线程
Eclipse RAP Multi-client but single server thread
我了解 RAP 如何创建作用域,并为每个客户端创建特定的线程等等。我也了解应用程序范围在多个客户端中是如何独特的,但是我不知道如何以单线程方式访问该特定范围。
我想要一个服务器端(可以访问数据库和其他东西),它是一个单一的执行,以确保它具有所有事务的全局知识,并且来自客户端的请求是按顺序而不是并行执行的。
目前我正在从 UI 访问应用程序上下文,如下所示:
synchronized( MyServer.class ) {
ApplicationContext appContext = RWT.getApplicationContext();
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
myServer.doSomething(RWTUtils.getSessionID());
}
即使我在那里访问 myServer 对象并触发请求,执行仍然会在 UI 线程中 运行。
现在确保顺序的唯一方法是在我的服务器上使用 synchronized
public class MyServer {
String text = "";
public void doSomething(String string) {
try {
synchronized (this) {
System.out.println("doSomething - start :" + string);
text += "[" + string + "]";
System.out.println("text: " + (text));
Thread.sleep(10000);
System.out.println("text: " + (text));
System.out.println("doSomething - stop :" + string);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
有没有更好的方法可以不用自己管理线程同步?
欢迎任何帮助
编辑:
为了更好地解释我自己,这就是我的意思。要么我相信数据库能够正确处理多个请求,并且我还必须以同步方式处理一些其他知识以在客户端之间共享信息(示例 A),或者我找到一个解决方案,其中另一个线程处理这两者(示例 B),知识和数据库。当然,这里的问题是一个客户端可能会阻塞其他客户端,但是对于长动作来说,这是可以用后台线程来管理的,大多数不会有问题。我最初的问题是,应用程序范围内是否已经有一些特定的线程执行示例 B,或者示例 A 是否真的可行?
结论(到目前为止)
基本上,选项 A) 是可行的方法。对于数据库访问,它需要连接池,对于共享信息,它需要对关键对象进行深思熟虑的同步。主要注意数据库设计和对象的同步,确保两个客户端不能同时写入不兼容的数据(例如写入相互矛盾的条目,使结果依赖于写入顺序)。
首先,您在第一个片段中创建 MyServer
的方式不是线程安全的。您可能会创建多个 MyServer
.
实例
您需要同步创建 MyServer
,例如:
synchronized( MyServer.class ) {
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
}
另请参阅此 post How to implement thread-safe lazy initialization? 了解其他可能的解决方案。
此外,您的代码在客户端线程(即 UI 线程)上调用 doSomething()
,这将导致每个客户端等待,直到处理其他客户端的未决请求。客户端 UI 将变得无响应。
要解决此问题,您的代码应从后台线程调用 doSomething()
(或任何其他长运行 操作)(另请参阅
Threads in RAP)
后台线程完成后,您应该使用Server Push更新UI。
我了解 RAP 如何创建作用域,并为每个客户端创建特定的线程等等。我也了解应用程序范围在多个客户端中是如何独特的,但是我不知道如何以单线程方式访问该特定范围。
我想要一个服务器端(可以访问数据库和其他东西),它是一个单一的执行,以确保它具有所有事务的全局知识,并且来自客户端的请求是按顺序而不是并行执行的。
目前我正在从 UI 访问应用程序上下文,如下所示:
synchronized( MyServer.class ) {
ApplicationContext appContext = RWT.getApplicationContext();
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
myServer.doSomething(RWTUtils.getSessionID());
}
即使我在那里访问 myServer 对象并触发请求,执行仍然会在 UI 线程中 运行。
现在确保顺序的唯一方法是在我的服务器上使用 synchronized
public class MyServer {
String text = "";
public void doSomething(String string) {
try {
synchronized (this) {
System.out.println("doSomething - start :" + string);
text += "[" + string + "]";
System.out.println("text: " + (text));
Thread.sleep(10000);
System.out.println("text: " + (text));
System.out.println("doSomething - stop :" + string);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
有没有更好的方法可以不用自己管理线程同步?
欢迎任何帮助
编辑: 为了更好地解释我自己,这就是我的意思。要么我相信数据库能够正确处理多个请求,并且我还必须以同步方式处理一些其他知识以在客户端之间共享信息(示例 A),或者我找到一个解决方案,其中另一个线程处理这两者(示例 B),知识和数据库。当然,这里的问题是一个客户端可能会阻塞其他客户端,但是对于长动作来说,这是可以用后台线程来管理的,大多数不会有问题。我最初的问题是,应用程序范围内是否已经有一些特定的线程执行示例 B,或者示例 A 是否真的可行?
结论(到目前为止)
基本上,选项 A) 是可行的方法。对于数据库访问,它需要连接池,对于共享信息,它需要对关键对象进行深思熟虑的同步。主要注意数据库设计和对象的同步,确保两个客户端不能同时写入不兼容的数据(例如写入相互矛盾的条目,使结果依赖于写入顺序)。
首先,您在第一个片段中创建 MyServer
的方式不是线程安全的。您可能会创建多个 MyServer
.
您需要同步创建 MyServer
,例如:
synchronized( MyServer.class ) {
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
}
另请参阅此 post How to implement thread-safe lazy initialization? 了解其他可能的解决方案。
此外,您的代码在客户端线程(即 UI 线程)上调用 doSomething()
,这将导致每个客户端等待,直到处理其他客户端的未决请求。客户端 UI 将变得无响应。
要解决此问题,您的代码应从后台线程调用 doSomething()
(或任何其他长运行 操作)(另请参阅
Threads in RAP)
后台线程完成后,您应该使用Server Push更新UI。