加载多个arraylist实例后,Runnable变得非常慢

时间:2014-04-20 21:09:17

标签: java multithreading swing

我试图与个人" Person"进行小型模拟游戏。类。我使用JFrame创建一个窗口并使用Runnable进行实时模拟。但是,当我创建更多Person实例时,Runnable变得非常慢。我拥有的实例越多,它就越慢。有没有更好的方法呢?或者我应该尝试使用SQL数据库而不是文本文件来存储数据?它只是代码的一部分,如果需要我会添加更多代码。非常感谢你。

public class Main extends JFrame实现了ActionListener {

private static final long serialVersionUID = 1L;
private JTextField textField;
private JTextArea textArea;

// create a list of people, each include person.java class
private List<Person> people = new ArrayList<Person>();

// set the number of miliseconds in a day
// 86400 = 24 hr x 60 min x 60 s
private int lengthOfDay = 100;
private int timeCounter = 0;
private int timeCounterPause = lengthOfDay / 24;
private int timeOfDay = 0;
private int hourOfDay = 0;
private int lengthOfYear = lengthOfDay * 365;
private int dayOfWeek = 1; // day starts monday
private String dayOfWeekS = "";


// boolean for stop Runnable
private volatile boolean stopRequested = false;

// runnable "run" class
Runnable simulation = new Runnable() {
    public void run() {
        try {
            while (!stopRequested) {

                for (int i = 0; i < people.size(); i++) {

                    // determine time of day
                    timeOfDay = timeOfDay + timeCounterPause;
                    if (timeOfDay > lengthOfDay) {
                        timeOfDay = timeOfDay % lengthOfDay;

                        // assign int to string dayOfWeekS
                        assignDay();
                    }

                    // display day of week if set visible (focused)
                    if (people.get(i).getVisible() && hourOfDay < 1) {
                        textArea.append(dayOfWeekS + "\n");
                    }

                    hourOfDay = timeOfDay / (lengthOfDay / 24);
                    people.get(i).setAge((float) (people.get(i).getAgeInMs() / (float)lengthOfYear));


                    // show time if focused
                    if (people.get(i).getVisible()) {
                        // textArea.append(hourOfDay +"o'clock\n");
                    }

                    // go to school
                    if (people.get(i).getFinishedSchool() == false && dayOfWeek != 6 && dayOfWeek != 7) {
                        people.get(i).goToSchool(timeOfDay);
                    } else if (people.get(i).getFinishedSchool() == true) {
                        people.get(i).findWork();
                    }

                    // go to work if has work, and not on weekends
                    if (!people.get(i).getProfession().equals("none") && dayOfWeek != 6
                            && dayOfWeek != 7)
                        people.get(i).goToWork(timeOfDay);

                    // check alive
                    people.get(i).checkAlive();

                    // sleep at night
                    people.get(i).sleep(timeOfDay);

                    // interval between each time status are checked
                    Thread.sleep(timeCounterPause);

                    // adjust ageInMs
                    people.get(i).setAgeInMs(people.get(i).getAgeInMs() + timeCounterPause);

                    // if alive is false, then remove the person
                    // remove person as the last thing to run
                    if (!people.get(i).getAlive()) {
                        people.remove(i);
                        }

                }
                timeCounter++;
            }
        } catch (InterruptedException iex) {
        }
    }
};

// method to stop Runnable
public void requestStop() {
    stopRequested = true;
}

public Main() {
    super("Simulation");

    textField = new JTextField(20);
    textField.setText("Enter your commands here.");
    textField.selectAll();
    textField.setForeground(new Color(0, 204, 0));
    textField.setBackground(Color.BLACK);
    textField.addActionListener(this);

    textArea = new JTextArea(40, 40);
    textArea.setEditable(false);
    textArea.setForeground(new Color(0, 204, 0));
    textArea.setBackground(Color.BLACK);

    JScrollPane scrollPane = new JScrollPane(textArea,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

    GridBagLayout gridBag = new GridBagLayout();
    Container contentPane = getContentPane();
    contentPane.setLayout(gridBag);
    GridBagConstraints c = new GridBagConstraints();
    c.gridwidth = GridBagConstraints.REMAINDER;

    c.fill = GridBagConstraints.HORIZONTAL;
    gridBag.setConstraints(textField, c);
    contentPane.add(textField);

    c.fill = GridBagConstraints.BOTH;
    c.weightx = 1.0;
    c.weighty = 1.0;
    gridBag.setConstraints(scrollPane, c);
    contentPane.add(scrollPane);

    // things to do when window opens
    addWindowListener(new WindowAdapter() {
        public void windowOpened(WindowEvent e) {
            loadSimulation();
            // load all data of each person
            loadPeople();

            // create thread when window is loaded
            Thread thr = new Thread(simulation);
            thr.start();
        }
    });

    // things to do when window closes
    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {

            savePeople();
            saveSimulation();
        }
    });
}

public void actionPerformed(ActionEvent event) {

    String prompt = textField.getText();
    String[] words = prompt.split("\\s+");

    // respond to commands
    switch (words[0]) {
    case "create":
        if (words[1].equals("person")) {
            createPerson();
        } else {
            textArea.append("Create what?\n");
        }
        break;
    case "focus":
        focus(words[1], words[2]);
        break;
    case "unfocus":
        unfocus();
        break;
    case "topCash":
        topCash();
        break;
    case "topAge":
        topAge();
        break;
    case "topIQ":
        topIQ();
        break;
    default:
        textArea.append("I don't know what you are saying.");
        break;
    }
    textField.selectAll();
}

public static void main(String[] args) {
    JFrame.setDefaultLookAndFeelDecorated(true);
    Main window = new Main();
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.pack();
    window.setVisible(true);
    window.getContentPane().setBackground(Color.BLACK);

}

1 个答案:

答案 0 :(得分:0)

你做了

Thread.sleep(timeCounterPause)

对于您检查的每个人,因此对于您添加的每个人,该循环需要4.166(lengthOfDay / 24)ms更长的时间。 如果你想让timeCounter暂停完成状态检查的更新间隔,你应该把它放在

之外
for (int i = 0; i < people.size(); i++) {

环。