Ril*_*ark 6 java google-app-engine thread-safety
除了以下Memcache的使用之外,我的java appengine项目不会在请求之间保持任何状态:
if (the memcache doesn't think a cleanup task is already running) schedule another cleanup task)之后批量清理任务的方法.我没有对任何对象的全局/静态引用,除了:
static ThreadLocal<User>对象中.这意味着每个请求都会获得自己的用户副本,对吧?static DataCoordinator对象中的一种全局变量保存.我需要注意什么才能使我的代码线程安全?我是否需要synchronized在我的DataCoordinator实现中的每个方法声明中抛出一个关键字,因为多个线程可以访问它?这是真的,该ThreadLocal<User>物体总会让一个单独的User对象为每个线程,使每个请求将被单独认证?
我是线程安全思维的新手.我该怎么读?
感谢您的帮助,并对缺乏特异性感到抱歉.
您应该注意的第一件事是应用引擎可以在多个服务器上复制您的应用程序.这意味着您的静态变量仅在一台服务器上是唯一的.因此,您DataCoordinator将仅协调单个服务器上的数据访问.因此,如果您需要为运行应用程序的所有服务器提供公共数据,则应始终使用数据存储(或在某些情况下使用gae HTTP会话机制).
关于线程安全性DataCoordinator:如果这些方法没有以线程安全的方式实现,则只需要同步此协调器的方法.例如,您不需要同步任何不访问任何实例/静态数据但仅从数据存储区获取数据的方法.如果方法访问可变的公共实例/静态数据(也同时写入),则在大多数情况下,您可以在特定监视器上同步访问的数据,而不是在整个协调器上进行同步.
关于ThreadLocal用于存储身份验证令牌的问题:您可以这样做(我这样做是为了对GWT请求工厂请求的gae中的用户身份验证),是的,只要您为该线程设置了它,每个线程都将拥有它自己的变量值.这意味着它是最好的,以确保该变量设置为每个线程,这是adviceable使用try- finally将其设置使用后最终删除认证数据之后-块.为什么?否则可能发生的最糟糕的事情是属于用户B的请求的线程仍然具有用户A的身份验证令牌.这是因为应用程序服务器中使用的线程通常在请求之间汇集而不是清理并重新创建.
因为我还没有使用它,所以我对memcache一无所知.
通常,您必须知道服务器可以同时处理任何Web请求(servlet/JSP/...).因此,这些线程访问的任何可变共享资源都应该以线程安全的方式同步或实现.
也许http://download.oracle.com/javase/tutorial/essential/concurrency/是一个很好的读入它的起点.
| 归档时间: |
|
| 查看次数: |
2354 次 |
| 最近记录: |