Java 使用与ConcurrentHashMap同步的复合操作(包含+;获取+;放置)
您能否通读下面的代码并帮助我知道在本例中是否需要将synchronized关键字与并发哈希映射一起使用 主要的问题是我不明白什么时候需要在并发哈希映射的复合操作中使用同步关键字。有人能帮忙吗Java 使用与ConcurrentHashMap同步的复合操作(包含+;获取+;放置),java,concurrency,Java,Concurrency,您能否通读下面的代码并帮助我知道在本例中是否需要将synchronized关键字与并发哈希映射一起使用 主要的问题是我不明白什么时候需要在并发哈希映射的复合操作中使用同步关键字。有人能帮忙吗 import java.util.Map; import java.util.concurrent.BlockingDeque; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorSe
import java.util.Map;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
class Pair {
public final Integer x;
public final Integer y;
public Pair(Integer x, Integer y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((x == null) ? 0 : x.hashCode());
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (x == null) {
if (other.x != null)
return false;
} else if (!x.equals(other.x))
return false;
if (y == null) {
if (other.y != null)
return false;
} else if (!y.equals(other.y))
return false;
return true;
}
}
class Order{
int clOrdId;
int origClOrdId;
String symbol;
int qty;
double price;
@Override
public String toString() {
return "Order [clOrdId=" + clOrdId + ", origClOrdId=" + origClOrdId + ", symbol=" + symbol + ", qty=" + qty
+ ", price=" + price + ", side=" + side + "]";
}
char side;
Order(int clOrdId,String symbol,int qty,double price,char side){
this.clOrdId=clOrdId;
this.symbol=symbol;
this.qty=qty;
this.price=price;
this.side=side;
}
Order(int clOrdId,int origClOrdId,String symbol,int qty,double price,char side){
this.clOrdId=clOrdId;
this.origClOrdId=origClOrdId;
this.symbol=symbol;
this.qty=qty;
this.price=price;
this.side=side;
}
}
class Message {
int sessionId;
Order order;
Message(int sessionId, Order order) {
this.sessionId = sessionId;
this.order = order;
}
@Override
public String toString() {
return "Message [sessionId=" + sessionId + ", order=" + order + "]";
}
}
/*
* Different clients can submit different messages 1. Each message has a
* sessionId and a string msg 2. Each of the messages on a particular session
* need to be processed sequentially
*/
public class Concurrency {
private Map<Integer, BlockingDeque<Runnable>> pendingTasks = new ConcurrentHashMap<>();
private Map<Pair,Order> orderMap = new ConcurrentHashMap<>();
private ExecutorService executorService = Executors.newFixedThreadPool(13);
public void submitMsg(final Message msg) {
submitTask(msg, () -> {
if(msg.order.origClOrdId==0){
print("Received new order msg " + msg);
sleep(1000);
}else{
Pair key = new Pair(msg.sessionId,msg.order.origClOrdId);
if(orderMap.containsKey(key)){
if(isOnlyAggressivePriceMod(msg, key) ){
print("Aggressive price modification "+ msg);
}else if(isOnlyQtyModUp(msg, key)){
print(" Quantity modification up only for "+ msg);
}else if(isOnlyQtyDown(msg, key)){
print(" Quantity modification down only for "+ msg);
}
}
}
orderMap.put(new Pair(msg.sessionId,msg.order.clOrdId), msg.order);
});
}
private boolean isOnlyQtyDown(final Message msg, Pair key) {
return msg.order.qty<orderMap.get(key).qty && Double.compare(msg.order.price,orderMap.get(key).price)==0;
}
private boolean isOnlyQtyModUp(final Message msg, Pair key) {
return msg.order.qty>orderMap.get(key).qty && Double.compare(msg.order.price,orderMap.get(key).price)==0;
}
private boolean isOnlyAggressivePriceMod(final Message msg, Pair key) {
return ((Double.compare(msg.order.price,orderMap.get(key).price)>0 && msg.order.side=='B') ||
(Double.compare(msg.order.price,orderMap.get(key).price)<0 && msg.order.side=='S')) && Double.compare(msg.order.qty,orderMap.get(key).qty)==0;
}
private void sleep(int time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void print(String msg){
System.out.println(msg);
}
private void submitTask(final Message msg, Runnable task) {
synchronized(pendingTasks){
if (pendingTasks.containsKey(msg.sessionId)) {
pendingTasks.get(msg.sessionId).add(task);
return;
}
}
BlockingDeque<Runnable> pendingTasksPerSession = new LinkedBlockingDeque<Runnable>();
pendingTasksPerSession.push(task);
pendingTasks.put(msg.sessionId, pendingTasksPerSession);
executorService.submit(new SynchronizedTask(msg, task));
}
public class SynchronizedTask implements Runnable {
Message msg;
Runnable task;
public SynchronizedTask(Message msg, Runnable task) {
this.msg = msg;
this.task = task;
}
public void run() {
task.run();
BlockingDeque<Runnable> pendingTasksForSession = pendingTasks.get(msg.sessionId);
if (!pendingTasksForSession.remove(task)) {
return;
}
if (!pendingTasksForSession.isEmpty())
executorService.submit(new SynchronizedTask(msg, pendingTasksForSession.getFirst()));
}
}
public static void main(String args[]) {
Concurrency c = new Concurrency();
for(int i =1;i<10;i++){
c.submitMsg(new Message(i, new Order(10,"0001.HK",2000*i,200+i,'B')));
c.submitMsg(new Message(i, new Order(11,10,"0001.HK",1000*i,200+i,'B')));
c.submitMsg(new Message(i, new Order(12,11,"0001.HK",2000*i,201+i,'B')));
}
for(int i =1;i<10;i++){
c.submitMsg(new Message(i, new Order(10,"0001.HK",2000*i,200+i,'S')));
c.submitMsg(new Message(i, new Order(11,10,"0001.HK",1000*i,200+i,'S')));
c.submitMsg(new Message(i, new Order(12,11,"0001.HK",2000*i,201+i,'S')));
}
}
}
import java.util.Map;
导入java.util.concurrent.BlockingDeque;
导入java.util.concurrent.ConcurrentHashMap;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingDeque;
类对{
公共最终整数x;
公共最终整数y;
公共对(整数x,整数y){
这个.x=x;
这个。y=y;
}
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((x==null)?0:x.hashCode();
result=prime*result+((y==null)?0:y.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
配对其他=(配对)obj;
如果(x==null){
if(other.x!=null)
返回false;
}如果(!x.equals(other.x))
返回false;
如果(y==null){
if(other.y!=null)
返回false;
}else如果(!y.equals(other.y))
返回false;
返回true;
}
}
阶级秩序{
int-clOrdId;
int-origClOrdId;
字符串符号;
整数数量;
双倍价格;
@凌驾
公共字符串toString(){
返回“订单[clOrdId=“+clOrdId+”,origClOrdId=“+origClOrdId+”,symbol=“+symbol+”,qty=“+qty
+,price=“+price+”,side=“+side+”];
}
焦侧;
订单(整数clOrdId、字符串符号、整数数量、双倍价格、字符端){
this.clOrdId=clOrdId;
这个符号=符号;
该数量=数量;
这个。价格=价格;
这一方=另一方;
}
订单(整数clOrdId、整数origClOrdId、字符串符号、整数数量、双倍价格、字符端){
this.clOrdId=clOrdId;
this.origClOrdId=origClOrdId;
这个符号=符号;
该数量=数量;
这个。价格=价格;
这一方=另一方;
}
}
类消息{
int sessionId;
订单;
消息(int sessionId,Order){
this.sessionId=sessionId;
这个。顺序=顺序;
}
@凌驾
公共字符串toString(){
return“Message[sessionId=“+sessionId+”,order=“+order+””;
}
}
/*
*不同的客户端可以提交不同的消息1。每条消息都有一个
*sessionId和字符串msg 2。特定会话上的每条消息
*需要按顺序处理
*/
公共类并发{
私有映射pendingTasks=新的ConcurrentHashMap();
私有映射orderMap=新的ConcurrentHashMap();
私有ExecutorService ExecutorService=Executors.newFixedThreadPool(13);
公共无效提交消息(最终消息消息){
提交任务(消息,()->{
if(msg.order.origClOrdId==0){
打印(“收到新订单消息”+消息);
睡眠(1000);
}否则{
Pair key=新对(msg.sessionId、msg.order.origcloridd);
if(orderMap.containsKey(键)){
if(isOnlyAggressivePriceMod(消息,键)){
打印(“积极修改价格”+信息);
}else if(isOnlyQtyModUp(消息,键)){
打印(“仅针对“+msg”进行数量修改);
}否则如果(isOnlyQtyDown(消息,键)){
打印(“仅针对“+msg”进行数量修改);
}
}
}
put(新对(msg.sessionId、msg.order.clOrdId)、msg.order);
});
}
专用布尔值isOnlyQtyDown(最终消息消息消息,配对密钥){
返回msg.order.qtyorderMap.get(key.qty&&Double.compare(msg.order.price,orderMap.get(key.price)==0;
}
私有布尔值isOnlyAggressivePriceMod(最终消息消息消息,配对密钥){
return((Double.compare(msg.order.price,orderMap.get(key.price)>0&&msg.order.side='B')|
(Double.compare(msg.order.price、orderMap.get(key.price)你应该真正定义你所遇到的问题,因为你现在要求某人查看整个代码并分析它…这可能属于codereview。你应该真正定义你所遇到的问题,因为你现在要求某人查看整个代码并分析它…这可能属于codereview。