我遇到了以下代码,并指出了一些不一致之处-多线程安全代码。
Angular CLI: 1.6.56
Node: 8.9.4
OS: linux x64
Angular: 5.2.1
... animations, common, compiler, compiler-cli, core, forms
... http, platform-browser, platform-browser-dynamic
... platform-server, router
@angular/cdk: 5.1.0
@angular/cli: 1.6.5
@angular/material: 5.1.0
@angular-devkit/build-optimizer: 0.0.41
@angular-devkit/core: 0.0.28
@angular-devkit/schematics: 0.0.51
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.5
@schematics/angular: 0.1.16
typescript: 2.6.2
webpack: 3.10.0
答案 0 :(得分:4)
这里只是一些观察结果:
String
is a very bad idea->在clusterKey
和serverKey
上进行同步可能无法达到预期的效果。ConcurrentHashMap
和ConcurrentHashSet
。尽管没有更多背景信息,但实际上不可能回答这个问题。似乎代码编写者希望安全地为每个clusterKey
和serverKey
创建1个映射,以便只能将用户添加一次。
一种(可能更好)的方法是仅将synchronize
上的clusters
放在地图本身上,那么您很安全,因为只有一个线程可以读取和/或写入该地图。
另一种方式是使用自定义Lock
,也许一个用于读取,另一个用于写入,尽管如果一个线程正在向Map
写入而另一个线程正在写入public function new(Request $request){
$user = new Client();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return [
'form' => $form->createView()
];
}
,则可能再次导致不一致。从中读取确切的值。
答案 1 :(得分:2)
代码看起来像Double checked locking idiom的非完整版本,有时用于延迟初始化。阅读提供的链接,了解为什么这是一个非常糟糕的实现。
给定代码的问题是它间歇性地失败。当有多个线程试图使用相同的键(或具有相同哈希码的键)在地图上工作时,存在竞争状态,这意味着第一个创建的地图可能会被第二个哈希图替换。
答案 2 :(得分:1)
1-同步试图避免两个线程同时在该Map中创建新的Entry。第二个必须等待,这样他的(servers==null)
也不会返回true
。
2-该users
列表似乎不在范围内,但似乎不需要同步。也许程序员知道没有重复的userId,或者他不在乎一次又一次地重置同一用户。
3- ConcurrentHashMap也许是