Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中线程原子性问题的解决_Java_Multithreading_Atomicity - Fatal编程技术网

Java中线程原子性问题的解决

Java中线程原子性问题的解决,java,multithreading,atomicity,Java,Multithreading,Atomicity,这个问题与我已经发布的下面的问题相结合 问题陈述:如何控制多个子线程之间共享的特定代码块只被访问一次 情景: 现在,我有一个场景,其中多个线程共享一个缓冲区资源(一个普通的并发列表),它用一些值更新列表,并在最后清除它。但我希望这个操作在原子性就绪的情况下执行。只有在第一个线程更新并清除列表后,第二个线程才应该开始更新列表。如果在第一个线程作业未完成的情况下操作不同步,则可能会导致数据问题 下面是代码片段,我试图在线程中放置一个同步块。这有意义吗?行吗?同步块内的行一次只能由一个线程访问,并且

这个问题与我已经发布的下面的问题相结合

问题陈述:如何控制多个子线程之间共享的特定代码块只被访问一次

情景:

现在,我有一个场景,其中多个线程共享一个缓冲区资源(一个普通的并发列表),它用一些值更新列表,并在最后清除它。但我希望这个操作在原子性就绪的情况下执行。只有在第一个线程更新并清除列表后,第二个线程才应该开始更新列表。如果在第一个线程作业未完成的情况下操作不同步,则可能会导致数据问题

下面是代码片段,我试图在线程中放置一个同步块。这有意义吗?行吗?同步块内的行一次只能由一个线程访问,并且块本身位于新生成的线程内

public void processControlMessage(final Message message) {
    try {
        lock.lock();
        RDPWorkflowControlMessage rdpWorkflowControlMessage = unmarshallControlMessage(message);
        if (rdpWorkflowControlMessage != null) {
            final String workflowName = rdpWorkflowControlMessage.getWorkflowName();
            final RdpWorkflowControlMessageType controlMessageType = rdpWorkflowControlMessage.getControlMessage();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (message instanceof TextMessage) {
                            if (controlMessageType != null && controlMessageType == RdpWorkflowControlMessageType.REFRESH) {
                                if (!isWorkflowBeingProcessed(workflowName)) {
                                    log.info("Processing workflow control message for the workflow " + workflowName);
                                    addShutdownHook(workflowName);
                                    List<String> matchingValues = new ArrayList<String>();
                                    matchingValues.add(workflowName);
                                    ConcreteSetDAO tasksSetDAO = taskEventListener.getConcreteSetDAO();
                                    ConcreteSetDAO workflowSetDAO = workflowEventListener.getConcreteSetDAO();
                                    tasksSetDAO.deleteMatchingRecords(matchingValues);
                                    workflowSetDAO.deleteMatchingRecords(matchingValues);
                                    List<RDPWorkflowTask> allTasks = fetchNewWorkflowItems(workflowName);
                                    //Will the below line be accessed and executed only by one thread??
                                    updateAndClearTasksandWorkflowSet(allTasks);
                                    removeWorkflowNameFromProcessingMap(workflowName);
                                } else {
                                    log.info("RDA cache clean up is already in progress for the workflow " + workflowName);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("Error extracting item of type RDPWorkflowControlMessage from message " + message);
                    }
                }
            }).start();
        }
    } finally {
        lock.unlock();
    }
}

private boolean isWorkflowBeingProcessed(final String workflowName) {
    if (controlMessageStateMap.get(workflowName) == null) {
        synchronized (this) {
            if (controlMessageStateMap.get(workflowName) == null) {
                log.info("Adding an entry in to the processing map for the workflow " + workflowName);
                controlMessageStateMap.put(workflowName, true);
                return false;
            }
        }
    }
    return true;
}

private void addShutdownHook(final String workflowName) {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            removeWorkflowNameFromProcessingMap(workflowName);
        }
    });
    log.info("Shut Down Hook attached for the thread processing the workflow " + workflowName);
}

private RDPWorkflowControlMessage unmarshallControlMessage(Message message) {
    RDPWorkflowControlMessage rdpWorkflowControlMessage = null;
    try {
        TextMessage textMessage = (TextMessage) message;
        rdpWorkflowControlMessage = marshaller.unmarshalItem(textMessage.getText(), RDPWorkflowControlMessage.class);
    } catch (Exception e) {
        log.error("Error extracting item of type RDPWorkflowTask from message " + message);
    }
    return rdpWorkflowControlMessage;
}

private List<RDPWorkflowTask> fetchNewWorkflowItems(String workflowName) {
    workflowRestServiceClient.initSSL();
    List<RDPWorkflowTask> allTasks = workflowRestServiceClient.fetchWorkflowSpecificTasks(workflowName);
    return allTasks;
}

private void updateAndClearTasksandWorkflowSet(List<RDPWorkflowTask> allTasks) {
    synchronized (this) {
           if (allTasks != null && allTasks.size() > 0) {
                taskEventListener.addRDPWorkflowTasks(allTasks);
                workflowEventListener.updateWorkflowStatus(allTasks);
                taskEventListener.getRecordsForUpdate().clear();
                workflowEventListener.getRecordsForUpdate().clear();
            }
    }

}

private synchronized void removeWorkflowNameFromProcessingMap(String workflowName) {
    if (workflowName != null
            && (controlMessageStateMap.get(workflowName) != null && controlMessageStateMap.get(workflowName))) {
        controlMessageStateMap.remove(workflowName);
        log.info("Thread processing the " + workflowName + " is released from the status map");
    }
}
public void processControlMessage(最终消息){
试一试{
lock.lock();
RDPWorkflowControlMessage RDPWorkflowControlMessage=unmarshallControlMessage(消息);
如果(rdpWorkflowControlMessage!=null){
最后一个字符串workflowName=rdpWorkflowControlMessage.getWorkflowName();
最终RdpWorkflowControlMessageType controlMessageType=rdpWorkflowControlMessage.getControlMessage();
新线程(newrunnable()){
@凌驾
公开募捐{
试一试{
如果(文本消息的消息实例){
if(controlMessageType!=null&&controlMessageType==RdpWorkflowControlMessageType.REFRESH){
如果(!IsWorkflowBeingProcessing(workflowName)){
log.info(“正在处理工作流的工作流控制消息”+工作流名称);
addShutdownHook(workflowName);
List matchingValues=new ArrayList();
匹配值。添加(workflowName);
ConcreteSetDAO tasksSetDAO=taskEventListener.getConcreteSetDAO();
ConcreteSetDAO workflowSetDAO=workflowEventListener.getConcreteSetDAO();
tasksSetDAO.deleteMatchingRecords(匹配值);
workflowSetDAO.deleteMatchingRecords(匹配值);
List allTasks=fetchNewWorkflowItems(workflowName);
//是否只有一个线程可以访问和执行下面的行??
UpdateAndClearTasks和WorkflowSet(所有任务);
从ProcessingMap(workflowName)中删除workflowName;
}否则{
log.info(“工作流的RDA缓存清理已在进行”+workflowName);
}
}
}
}捕获(例外e){
log.error(“从消息“+消息”中提取RDPWorkflowControlMessage类型的项时出错);
}
}
}).start();
}
}最后{
lock.unlock();
}
}
私有布尔值isWorkflowBeingProcessed(最终字符串workflowName){
if(controlMessageStateMap.get(workflowName)==null){
已同步(此){
if(controlMessageStateMap.get(workflowName)==null){
log.info(“在工作流的处理映射中添加条目”+workflowName);
controlMessageStateMap.put(workflowName,true);
返回false;
}
}
}
返回true;
}
私有void addShutdownHook(最终字符串workflowName){
Runtime.getRuntime().addShutdownHook(新线程(){
公开募捐{
从ProcessingMap(workflowName)中删除workflowName;
}
});
log.info(“为处理工作流的线程附加的关闭钩子”+workflowName);
}
专用RDPWorkflowControlMessage解组控件消息(消息消息消息){
RDPWorkflowControlMessage RDPWorkflowControlMessage=null;
试一试{
text消息text消息=(text消息)消息;
rdpWorkflowControlMessage=marshaller.UnmarshaleItem(textMessage.getText(),rdpWorkflowControlMessage.class);
}捕获(例外e){
log.error(“从消息“+消息中提取RDPWorkflowTask类型的项时出错”);
}
返回rdpWorkflowControlMessage;
}
私有列表fetchNewWorkflowItems(字符串workflowName){
workflowRestServiceClient.initSSL();
列出所有任务=workflowRestServiceClient.fetchWorkflowSpecificTasks(workflowName);
返回所有任务;
}
私有void updateAndClearTasks和WorkflowSet(列出所有任务){
已同步(此){
if(allTasks!=null&&allTasks.size()>0){
taskEventListener.addRDPWorkflowTasks(所有任务);
workflowEventListener.updateWorkflowStatus(所有任务);
taskEventListener.getRecordsForUpdate().clear();
workflowEventListener.getRecordsForUpdate().clear();
}
}
}
private synchronized void removeWorkflowNameFromProcessingMap(字符串workflowName){
如果(workflowName!=null
&&(controlMessageStateMap.get(workflowName)!=null&&controlMessageStateMap.get(workflowName))){
controlMessageStateMap.remove(workflowName);
log.info(“从状态映射中释放处理“+workflowName+”的线程”);
}
}

我认为你走错了方向。在processControlMessage()方法中,要多次锁定和释放对象。您正在某个ca中锁定实例
new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    synchronize(controlMessageStateMap) {
                    if (message instanceof TextMessage) {
                        if (controlMessageType != null && controlMessageType == RdpWorkflowControlMessageType.REFRESH) {
                            if (!isWorkflowBeingProcessed(workflowName)) {
                        ...
                    } // end of synchronize block
                } catch (Exception e) {
                    log.error("Error extracting item of type RDPWorkflowControlMessage from message " + message);
                }