为什么我的Thread不骑自行车?

时间:2013-01-28 20:13:31

标签: java multithreading

我遇到一个问题,我的线程没有循环,我不知道为什么。它运行run方法一次然后停止。这是我的代码。

public class LifeFrame extends JApplet{

    private Scanner scan;
    public FramePanel framePanel = new FramePanel();
    private JPanel buttonPanel = new JPanel();
    private JButton button1 = new JButton("Start");
    private JButton button2 = new JButton("Stop");
    private JButton button3 = new JButton("Reset");
    public ImageIcon onTemp = new ImageIcon(this.getClass().getResource("squareOn.png"));
    public ImageIcon offTemp = new ImageIcon(this.getClass().getResource("squareOff.png"));
    public Image lifeOn = onTemp.getImage();
    public Image lifeOff = offTemp.getImage();
    public boolean[][] lifeCheck = new boolean[20][20];
    public boolean[][] lifeHolder = new boolean[20][20];
    public boolean run = false;
    private Thread animator;

    public void init(){
        try {
            scan = new Scanner(new File("life100.txt"));
        } catch (FileNotFoundException e) {
            System.out.println("ERROR");
        }
        int temp = Integer.parseInt(scan.nextLine().trim());
        for(int i = 0; i < temp; i++)
            lifeHolder[Integer.parseInt(scan.next().trim())-1][Integer.parseInt(scan.nextLine().trim())-1] = true;

        framePanel.setSize(700,800);

        button1.setSize(100,60);
        button2.setSize(100,60);
        button3.setSize(100,60);
        ButtonHandler handler = new ButtonHandler();
        button1.addActionListener(handler);
        button2.addActionListener(handler);
        button3.addActionListener(handler);
        buttonPanel.setSize(300,60);
        buttonPanel.add(button1);
        buttonPanel.add(button2);
        buttonPanel.add(button3);
        buttonPanel.setBackground(new Color(71,68,68));

        add(framePanel, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.SOUTH);
        startThread();
        framePanel.repaint();
    }

    public void startThread(){
        animator = new Thread(framePanel);
        animator.start();
    }

    public class FramePanel extends JPanel implements Runnable{
        public FramePanel(){
            this.setLayout(new GridLayout(20, 20));
        }

        public void run(){

            long beforeTime, timeDiff, sleep;

            beforeTime = System.currentTimeMillis();

            while(run){
                cycle();

                timeDiff = System.currentTimeMillis() - beforeTime;
                sleep = 500 - timeDiff;

                if (sleep < 0)
                    sleep = 2;
                try {
                    Thread.sleep(sleep);
                } catch (InterruptedException e) {
                    System.out.println("Sleep Interrupted");
                }

                beforeTime = System.currentTimeMillis();
            }
        }

        public void cycle(){
            int neighbors = 0;
            for(int row = 0; row < lifeHolder.length; row++)
                for( int col = 0; col < lifeHolder[row].length; col++)
                    lifeCheck[row][col] = lifeHolder[row][col];

            for(int row = 0; row < lifeHolder.length; row++){
                for( int col = 0; col < lifeHolder[row].length; col++){
                    for(int r = row - 1; r <= row + 1; r++){
                        for(int c = col - 1; c <= col + 1; c++){
                            if(r >= 0 && c >= 0 && r < lifeHolder.length && c < lifeCheck[row].length)
                                if(lifeHolder[r][c])
                                    neighbors++;
                        }
                    }
                    if(lifeHolder[row][col]){
                        neighbors--;
                        if(neighbors < 2 || neighbors > 3)
                            lifeCheck[row][col] = false;
                    }else{
                        if(neighbors == 3)
                            lifeCheck[row][col] = true;
                    }
                    neighbors = 0;
                }
            }
            for(int row = 0; row < lifeHolder.length; row++)
                for( int col = 0; col < lifeHolder[row].length; col++)
                    lifeHolder[row][col] = lifeCheck[row][col];

            repaint();
        }

        public void paint(Graphics g){
            for(int r = 0; r < 20; r++)
                for(int r1 = 0; r1 < 20; r1++){
                    if(lifeHolder[r][r1]){
                        g.drawImage(lifeOn, r1*20 + 3, r*20 + 29, 20, 20, framePanel);
                    }else
                        g.drawImage(lifeOff, r1*20 + 3, r*20 + 29, 20, 20, framePanel);
                }
        }
    }

    private class ButtonHandler implements ActionListener{
        public void actionPerformed(ActionEvent event){
            if(event.getSource().equals(button1)){
                run = true;
                System.out.println(run);
            }
                if(event.getSource().equals(button2)){
                    run = false;
                    System.out.println(run);
                }else{
                    //reset
                }   
        }
    }
}

任何帮助将不胜感激。感谢。

4 个答案:

答案 0 :(得分:3)

您将run定义为false

你启动线程,线程开始执行run方法,并且(因为变量runfalse)它结束。

稍后,也许用户可以点击按钮并将变量run设置为true。但是当用户点击某个东西时,你的线程很久以前就已经退出了。

使用无限循环,使用run检查必须做某事或是否必须睡觉。在守护进程中设置线程,以便JVM在最后一个非守护程序线程结束时将其终止。

答案 1 :(得分:2)

因为变量run在启动时被定义为false

答案 2 :(得分:1)

启动线程时,run变量为false。该线程经过run方法一次,失败了循环条件,并且脱离了方法的底部并终止。

runButtonHandler设置为true时,该线程已经很久了。

我建议你不要试图管理你自己的线程,而是使用SwingWorker,它专门用于触发GUI事件的后台线程中的工作。

答案 3 :(得分:0)

一开始你设置

public boolean run = false;

然后再做

while(run){
[...]
}