Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.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_Singleton - Fatal编程技术网

使用java单例时,不同的方法会同时访问它,而它存储的信息会混淆

使用java单例时,不同的方法会同时访问它,而它存储的信息会混淆,java,singleton,Java,Singleton,我正在为我的大学班做这个项目,它相当大。该计划的目的是促进项目学生团队的形成。它使用GUI显示团队和指标,并允许项目经理在团队中交换学生,它还有一个算法,可以找到可以改进团队指标的交换。简而言之,它找到一个时间适合度最低的团队,并找到该团队中最不适合的学生,然后它循环遍历该学生,并尝试将该最不适合的学生与另一个团队的学生交换,如果成功,它会检查指标是否改善,如果是这样的话,它会切换回原始状态,并在GUI中打印此建议。该程序有一个单独的DataStorage类,它保存学生、团队、项目的哈希图 当我

我正在为我的大学班做这个项目,它相当大。该计划的目的是促进项目学生团队的形成。它使用GUI显示团队和指标,并允许项目经理在团队中交换学生,它还有一个算法,可以找到可以改进团队指标的交换。简而言之,它找到一个时间适合度最低的团队,并找到该团队中最不适合的学生,然后它循环遍历该学生,并尝试将该最不适合的学生与另一个团队的学生交换,如果成功,它会检查指标是否改善,如果是这样的话,它会切换回原始状态,并在GUI中打印此建议。该程序有一个单独的DataStorage类,它保存学生、团队、项目的哈希图

当我从GUI控制器类调用algorithm方法时,问题就出现了:当我移动学生或使用undo按钮时,学生会被随机交换(当发生任何更改时,我调用reload()方法刷新窗口,它会调用algorithm方法)。只有在使用算法方法时才会发生这种情况,所以我想象发生的情况是算法方法获取单例实例以访问数据,它尝试执行交换以度量度量,其他一些方法获取单例实例并获取错误的状态。我已经在getInstance方法中添加了关键字“synchronized”,但没有帮助,我尝试使用ConcurrentHashMap,但没有效果

有没有人知道我做错了什么,如何帮助我?如有任何意见,我将不胜感激

这是我的单身汉:

class DataStorage{
    private static DataStorage ds;
    private HashMap<String, Company> companies = new HashMap<String, Company>();
    private HashMap<String, Student> students = new HashMap<String, Student>();
    private HashMap<String, Project> projects = new HashMap<String, Project>();
    private HashMap<String, ProjectOwner> pOwners = new HashMap<String, ProjectOwner>();
    private ConcurrentHashMap<String, Team> teams = new ConcurrentHashMap<String, Team>();
    
    private DataStorage() {
    }
    
  public static synchronized DataStorage getInstance() 
  { 
      if (ds == null) 
          ds = new DataStorage();
      return ds; 
  } 
类数据存储{
私有静态数据存储;
私有HashMap公司=新HashMap();
private HashMap students=new HashMap();
私有HashMap项目=新建HashMap();
private HashMap pOwners=new HashMap();
私有ConcurrentHashMap团队=新ConcurrentHashMap();
私有数据存储(){
}
公共静态同步数据存储getInstance()
{ 
如果(ds==null)
ds=新数据存储();
返回ds;
} 
下面是使用算法方法的类:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

import exceptions.TeamNotFormedException;

public class ImprovementAlgo2 {
    static DataStorage hv = DataStorage.getInstance();
    

    
    
    //comparator to compare team fitness
    public static Comparator<Team> createComparator(){

         Comparator<Team> comp = Comparator.comparing(team -> {
            try {
                return team.calcTeamFitness();
            } catch (TeamNotFormedException e) {
                e.printStackTrace();
                return null;
            }
        }, Double::compare);
         return comp;
    }
    
    public static String giveSuggestion() throws TeamNotFormedException{

        Comparator<Team> comparator = createComparator();
        ArrayList<Team> sortedTeams = new ArrayList<Team>(hv.getTeams().values());
        Collections.sort(sortedTeams, comparator);  
       
        double oldMixSd = 0;
        double oldSDSS = 0;
        try {
        oldSDSS = CalculateMetrics.calcSDss();
        double oldSPSF = CalculateMetrics.calcSDpspf();
        double oldASSC = CalculateMetrics.calcSDassc();
        
        oldMixSd = 0.25*oldSPSF/25 + 0.25*oldASSC + 0.5*oldSDSS;
        } catch(Exception e) {}
        
        double newMixSd;
        double newSDSS;
        
        int teamNum = 0;
        int studNum = 0;
        //looping only through half the teams
        double maxTeamNum = hv.getTeams().size()/2;
        
        while(teamNum <= maxTeamNum ) {
            while(studNum<=4) {
        //Adding all members of the worst team to an array
        Team worstTeam = sortedTeams.get(0);
        ArrayList<Student> sortedWorsTStudents = new ArrayList<Student>();
        for (String memId : worstTeam.getMembers()) {
            sortedWorsTStudents.add(hv.getStudents().get(memId));
        }
        
        //sorting student of the team based on their suitability
        Comparator<Student> comp = InitialTeamSortingAlgo.createComparator(worstTeam);
        Collections.sort(sortedWorsTStudents,comp);
        
        //getting the least suitable student
        Student worstStudent = sortedWorsTStudents.get(0);

        boolean swapped = false;
        //trying to swap least suitable student in the team with a student from another team that's more suitable
        for (HashMap.Entry<String, Student> x : hv.getStudents().entrySet()) {
            try { 
                if(x.getValue().studSuitability(worstTeam) > worstStudent.studSuitability(worstTeam)) {
                    swapped = DataHandling.swapTeammembers(x.getKey(), worstStudent.getID());
                    
                    //checking if this improved SD, if not, we swap back and contrinue the loop
                    if(swapped==true) {
                        try {
                            newSDSS = CalculateMetrics.calcSDss();
                            //newMixSd = 0.25*CalculateMetrics.calcSDpspf()/25 + 0.25*CalculateMetrics.calcSDassc() + 0.5* CalculateMetrics.calcSDss();
                        }catch (Exception e) {
                            newSDSS = oldSDSS;
                            //newMixSd = oldMixSd;
                        }
                        if(newSDSS < oldSDSS) {
                            DataHandling.swapTeammembers(x.getKey(), worstStudent.getID());
                            return "Swap students " + x.getKey() + " and " + worstStudent.getID();
                        }
                    }
                }
            } catch (Exception e) {}
        }
        studNum++;
        }
        teamNum ++;
        }
        return "";
    }
}
import java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.HashMap;
导入异常。TeamNotFormedException;
公共课改进2{
静态DataStorage hv=DataStorage.getInstance();
//用于比较团队体能的比较器
公共静态比较器createComparator(){
比较器比较=比较器比较(团队->{
试一试{
return team.calcTeamFitness();
}捕获(TeamNotFormedException e){
e、 printStackTrace();
返回null;
}
}双:比较);
返回补偿;
}
公共静态字符串giveSuggestion()抛出TeamNotFormedException{
比较器比较器=createComparator();
ArrayList sortedTeams=新的ArrayList(hv.getTeams().values());
集合。排序(分类团队、比较者);
双oldMixSd=0;
双oldsds=0;
试一试{
oldSDSS=CalculateMetrics.calcSDss();
double-oldspf=CalculateMetrics.calcsdpsf();
double-oldASSC=CalculateMetrics.calcSDassc();
oldMixSd=0.25*oldspf/25+0.25*oldASSC+0.5*oldsds;
}捕获(例外e){}
双新混合SD;
双新闻决策支持系统;
int teamNum=0;
int studNum=0;
//只在一半的队伍中循环
double maxTeamNum=hv.getTeams().size()/2;
while(teamNum)
import exceptions.ExceedingMaxNumMembersException;
import exceptions.SystemException;
import exceptions.TeamNotFormedException;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;

import javax.swing.*;
import java.net.URL;
import java.util.*;

public class GUIController implements Initializable {
    private final DataStorage hv;

    @FXML
    private VBox mainContainer;

    @FXML
    private GridPane freeGrid;

    @FXML
    private BarChart<String, Number> percentageHist;

    @FXML
    private BarChart<String, Number> competencyHist;

    @FXML
    private BarChart<String, Number> skillGapHist;

    private GridPane[] teamGrids;
    
    @FXML
    private Button undoButton;
    
    @FXML
    private Label competencyLabel;
    
    @FXML
    private Label preferenceLabel;
    
    @FXML
    private Label skillGapLabel;
    
    @FXML
    private Label suggestionLabel;

     
    public GUIController() {
        try {
            hv = DataStorage.getInstance();
            hv.load();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    Stack<ArrayList<String>> history = new Stack <ArrayList<String>>();
    Stack<ArrayList<String>> future = new Stack <ArrayList<String>>();
    

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        teamGrids = new GridPane[5];
        for (int i = 0; i < 5; i++) {
            teamGrids[i] = (GridPane) mainContainer.lookup("#team" + (i + 1) + "Grid");
        }

        freeGrid.setOnDragOver(event -> {
            if (event.getGestureSource() != freeGrid &&
                    event.getDragboard().hasString()) {
                event.acceptTransferModes(TransferMode.MOVE);
            }
            event.consume();
        });
        
        //When student is dragged to a grid above teams it gets removed from team
        freeGrid.setOnDragDropped((DragEvent event) -> {
            event.acceptTransferModes(TransferMode.ANY);
            String s = event.getDragboard().getString();
            if (event.getGestureSource() != freeGrid &&
                    event.getDragboard().hasString()
            ) {
                Student student = hv.getStudents().get(s);
                Team team = hv.getTeams().get(student.getTeamID());
                team.removeMember(s);
                
                //Undo-redo saving info
                ArrayList<String> histEntry = new ArrayList();
                histEntry.add(team.getId());
                histEntry.add(student.getID());
                history.push(histEntry);;
                ArrayList<String> futEntry = new ArrayList();
                futEntry.add(null);
                futEntry.add(s);
                future.push(futEntry);
                reload();
            }
        });

        Map<String, Team> teams = hv.getTeams();
        List<String> teamIds = new ArrayList<>(teams.keySet());
        Collections.sort(teamIds);
        for (int i = 0; i < 5; i++) {
            GridPane gridPane = teamGrids[i];
            Label teamLabel = (Label) gridPane.lookup("#teamLabel");
            String teamName = teamIds.get(i);
            teamLabel.setText(teamName);
            Team team = teams.get(teamName);

            //Handles when student is dragged to the team
            gridPane.setOnDragOver(event -> {
                if (event.getGestureSource() != gridPane &&
                        event.getDragboard().hasString() &&
                        team.getMembers().size() < 4
                ) {
                    event.acceptTransferModes(TransferMode.MOVE);
                }
                event.consume();
            });

            gridPane.setOnDragDropped((DragEvent event) -> {
                event.acceptTransferModes(TransferMode.ANY);
                String s = event.getDragboard().getString();
                if (event.getGestureSource() != gridPane &&
                        event.getDragboard().hasString()
                ) {
                    Student student = hv.getStudents().get(s);
                    String oldTeamId = student.getTeamID();
                    if (student.getTeamID() != null) {
                        Team oldTeam = hv.getTeams().get(oldTeamId);
                        oldTeam.removeMember(s);
                        student.setTeamID(null);
                    }
                    try {
                        //this line is called when student is draggd to a team and dropped
                        team.addMember(student.getID());
                        ArrayList histEntry = new ArrayList();
                        histEntry.add(oldTeamId);
                        histEntry.add(s);
                        history.push(histEntry);
                        ArrayList futEntry = new ArrayList();
                        futEntry.add(team.getId());
                        futEntry.add(s);
                        future.push(futEntry);
                        
                        

                        reload();
                    }
                    catch (Exception e) {
                        try {
                            if (!teamName.equals(student.getTeamID())) {
                                if (oldTeamId != null) {
                                    Team oldTeam = hv.getTeams().get(oldTeamId);
                                    oldTeam.addMember(student.getID());
                                }
                            }
                        } catch (Exception ex) {
                            throw new IllegalStateException(ex);
                        }
                        Alert alert = new Alert(Alert.AlertType.WARNING);
                        alert.setTitle("Add team member error");
                        alert.setContentText(e.getMessage());
                        alert.showAndWait();
                    }
                }
            });
        }
        reload();
        
    }
    
public void undoEvent (){
    if(history.size()>0) {
    ArrayList<String> histItem = history.pop();
    String oldteamID = (String)histItem.get(0);
    String studID = (String)histItem.get(1);
    //Saving current state into future stack to redo
    String currentTeamID = hv.getStudents().get(studID).getTeamID();
    ArrayList<String> futItem = new ArrayList();
    futItem.add(currentTeamID);
    futItem.add(studID);
    
    if(currentTeamID!=null) {
    Team currentTeam = hv.getTeams().get(currentTeamID);
    currentTeam.removeMember(studID);
    }
    
    if(oldteamID != null) {
        try {
            Team oldTeam = hv.getTeams().get(oldteamID);
            oldTeam.addMember(studID);
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }   
    }
    reload();
    }}

public void redoEvent (){
    if(future.size()>0) {
    ArrayList<String> futItem = future.pop();
    String oldteamID = (String)futItem.get(0);
    String studID = (String)futItem.get(1);
    //Saving current state into future stack to redo
    String currentTeamID = hv.getStudents().get(studID).getTeamID();
    ArrayList<String> histItem = new ArrayList();
    histItem.add(currentTeamID);
    histItem.add(studID);
    
    if(currentTeamID!=null) {
    Team currentTeam = hv.getTeams().get(currentTeamID);
    currentTeam.removeMember(studID);
    }
    
    if(oldteamID != null) {
        try {
            Team oldTeam = hv.getTeams().get(oldteamID);
            oldTeam.addMember(studID);
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }   
    }
    
    reload();
    }}

    private void reload() {
        Map<String, Student> freeStudents = new HashMap<>(hv.getStudents());
        freeGrid.getChildren().removeIf(node -> node.getClass() == Label.class);

        for (GridPane gridPane : teamGrids) {
            gridPane.getChildren().removeIf(node -> node.getClass() == Label.class && !"teamLabel".equals(node.getId()));
            gridPane.setGridLinesVisible(true);
        }

        for (int i = 0; i < 5; i++) {
            GridPane gridPane = teamGrids[i];
            Label teamLabel = (Label) gridPane.lookup("#teamLabel");
            Team team = hv.getTeams().get(teamLabel.getText());
            List<String> memberIds = team.getMembers();;
            Collections.sort(memberIds);

            for (int j = 0; j < memberIds.size(); j++) {
                String memberId = memberIds.get(j);
                freeStudents.remove(memberId);

                Student student = hv.getStudents().get(memberId);
                Label memberLabel = new Label(memberId);
                memberLabel.setOnDragDetected((MouseEvent event) -> {
                    Dragboard dragboard = memberLabel.startDragAndDrop(TransferMode.ANY);
                    ClipboardContent content = new ClipboardContent();
                    content.putString(memberId);
                    dragboard.setContent(content);
                    event.consume();
                });
                GridPane.setValignment(memberLabel, VPos.CENTER);
                GridPane.setHalignment(memberLabel, HPos.CENTER);
                gridPane.add(memberLabel, 0, j + 1);
            }
        }

        List<String> freeStudentIds = new ArrayList<>(freeStudents.keySet());
        Collections.sort(freeStudentIds);

        for (int i = 0; i < freeStudentIds.size(); i++) {
            String memberId = freeStudentIds.get(i);
            Student student = freeStudents.get(memberId);
            student.setTeamID(null);
            Label memberLabel = new Label(memberId);
            memberLabel.setOnDragDetected((MouseEvent event) -> {
                Dragboard dragboard = memberLabel.startDragAndDrop(TransferMode.ANY);
                ClipboardContent content = new ClipboardContent();
                content.putString(memberId);
                dragboard.setContent(content);
                event.consume();
            });
            freeGrid.add(memberLabel, i / 2, i % 2);
            GridPane.setValignment(memberLabel, VPos.CENTER);
            GridPane.setHalignment(memberLabel, HPos.CENTER);
        }

        calcHists();
       // displaySuggestion();
        hv.save();
    }
    
//    public void displaySuggestion() {
//      try {
//          suggestionLabel.setText(ImprovementAlgo2.giveSuggestion());
//      }catch (Exception e){
//          System.out.println("Exception in displaySuggestion: " + e.getMessage());
//      }
//    }
    
    private void calcHists() {
        Map<String, Team> teams = hv.getTeams();
        List<String> teamIds = new ArrayList<>(teams.keySet());
        Collections.sort(teamIds);

        percentageHist.getData().clear();
        XYChart.Series<String, Number> percentageDataSeries = new XYChart.Series<>();
        for (String teamId : teamIds) {
            Team team = teams.get(teamId);
            try {
                int percentage = team.percentageFirstSecondPreferences();
                percentageDataSeries.getData().add(new XYChart.Data<>(teamId, percentage));
            }
            catch (TeamNotFormedException e) {
                System.out.println("Exception in calcHists: " + e.getMessage());
            }
        }
        percentageHist.getData().add(percentageDataSeries);
        try {
            preferenceLabel.setText("SD: " + MyMath.round(CalculateMetrics.calcSDpspf(),2));
        } catch (Exception e) {
            e.getMessage();
        }
        


        competencyHist.getData().clear();
        String[] params = {"P", "A", "W", "N"};
        for (String param : params) {
            XYChart.Series<String, Number> dataSeries = new XYChart.Series<>();
            dataSeries.setName(param);
            for (String teamId : teamIds) {
                Team team = teams.get(teamId);
                try {
                    Map<String, Double> avg = team.averageGrade();
                    dataSeries.getData().add(new XYChart.Data<>(teamId, avg.get(param)));
                }
                catch (TeamNotFormedException e) {
                    System.out.println("Exception in competencyHist: " + e.getMessage());
                }
            }
            competencyHist.getData().add(dataSeries);
            try {
                competencyLabel.setText("SD: " + MyMath.round(CalculateMetrics.calcSDassc(),2));
            } catch (Exception e) {
                e.getMessage();
            }
        }

        skillGapHist.getData().clear();
        XYChart.Series<String, Number> skillGapDataSeries = new XYChart.Series<>();
        for (String teamId : teamIds) {
            Team team = teams.get(teamId);
            try {
                double skillShortfall = team.skillShortfall();
                skillGapDataSeries.getData().add(new XYChart.Data<>(teamId, skillShortfall));
            }
            catch (TeamNotFormedException e) {
                System.out.println("Exception in skillGapHist: " + e.getMessage());
            }
        }
        skillGapHist.getData().add(skillGapDataSeries);
        try {
            skillGapLabel.setText("SD: " + MyMath.round(CalculateMetrics.calcSDss(),2));
        } catch (Exception e) {
            e.getMessage();
        }
    }

}