无法取消WorkerThread。当执行取消功能时,它仍然执行

时间:2019-10-16 15:58:18

标签: java multithreading swing swingworker

该项目与我当前的问题有关。我想我已经解决了问题,但是当我想单击按钮取消工作线程时,还会出现另一个问题。 doInBackground仍在运行。(Printf(“ Runing” + this.index)仍在运行) 这些是我的代码:

import java.awt.Color;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingWorker;

public class Robot extends SwingWorker< Void ,Integer> {
    public int x;
    public static int i = 0;
    public int index;
    public int y;
    public Color color;
    public final int speed = 10;
    Robot(int x , int y , Color color)
    {
        this.x = x;
        this.y = y;
        this.color = color;
        this.index = i;
        i++;
    }
    public void move_90()
    {
        this.y += speed;
    }

    public void move_270()
    {
        this.y -= speed;
    }

    public void move_180()
    {
        this.x -= speed;
    }

    public void move_0()
    {
        this.x += speed;
    }

    public void move_45()
    {
        this.x += speed;
        this.y += speed;
    }

    public void move_135()
    {
        this.x -= speed;
        this.y += speed;
    }

    public void move_225()
    {
        this.x -= speed;
        this.y -= speed;
    }

    public void move_315()
    {
        this.x += speed;
        this.y -= speed;
    }

    public void move()
    {
        Random temp = new Random();
        int rand = temp.nextInt(8);
        switch(rand + 1)
        {
            case 1: move_0();
            break;
            case 2: move_135();
            break;
            case 3: move_180();
            break;
            case 4: move_225();
            break;
            case 5: move_270();
            break;
            case 6: move_315();
            break;
            case 7: move_45();
            break;
            case 8: move_90();
            break;
        }
    }
    @Override
    protected Void doInBackground() throws Exception {
         while(true)
        {
            System.out.println("Runing" + this.index);
            move();
            if(this.x < 40) this.x = 40;
            if(this.x > PlayField.width - 40) this.x = (PlayField.width - 40);
            if(this.y < 40) this.y = 40;
            if(this.y > PlayField.height - 40) this.y = (PlayField.height - 40);
             try {
                 Thread.sleep(200);
             } catch (InterruptedException ex) {
                 Logger.getLogger(Robot.class.getName()).log(Level.SEVERE, null, ex);
             }
        }
    }

    @Override
    protected void done() {
        super.done();
        System.out.println("done");//To change body of generated methods, choose Tools | Templates.
    }

}

这是我的RobotModel类:

import java.awt.Color;
import java.util.LinkedList;
public class RobotModel {
    public static final int MAX = 8;
    public LinkedList<Robot> model = new LinkedList<Robot>();
    public void add_New_Robot()
    {
        Robot temp = new Robot( 40 , 40 , Color.BLUE);
        temp.execute();
        model.addFirst(temp);
    }
}

这是GameMain类

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GameMain extends JFrame {
    RobotModel a;
    PlayField field;
    public void Game_Start()
    {
        a = new RobotModel();
        field = new PlayField(500 , 500, Color.yellow);
        RobotWorld world = new RobotWorld(a);
        world.setPreferredSize(new Dimension(500 , 500));
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        world.robot_Model.add_New_Robot();
        this.setSize(field.width , field.height);
        this.setLayout(new GridLayout());
        this.add(world);
        JButton but = new JButton();
        but.setPreferredSize(new Dimension(50, 20));
        but.setText("STOP");
        but.setVisible(true);
        but.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                world.robot_Model.model.get(0).cancel(true);
                world.robot_Model.model.remove(0);
            }
        });
        this.add(but);
        this.setVisible(true);
        world.repaint();
    }
    public void gameUpdate(){
    Thread gameThread = new Thread(){
        public void run(){
            while(true){
                //refresh screen
                repaint();
                //give other threads time
                try{
                    Thread.sleep(5);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    };

    gameThread.start();
}



    public static void main(String args[])
    {
        GameMain main = new GameMain();
        main.Game_Start();
        main.gameUpdate();

    }
}

这是RobotWorld类

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class RobotWorld extends JPanel {
    public RobotModel robot_Model;

    public RobotWorld(RobotModel robot_Model) {
        super();
        this.robot_Model = robot_Model;
        this.setSize(PlayField.width , PlayField.height);
        this.setVisible(true);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D graphic = (Graphics2D)g;
        for(Robot x : this.robot_Model.model )
        {
            graphic.setColor(x.color);
            graphic.drawOval(x.x, x.y, 40, 40);
        }
    }

}

这是PlayField类

package com.mycompany.test;

import java.awt.Color;

public class PlayField {
    public static int width;
    public static int height;
    public static Color fill_Color;
    PlayField(int width , int height , Color fill_Color)
    {
        this.width = width;
        this.height = height;
        this.fill_Color = fill_Color;
    }
}

MadProgramer给了我一个令人惊讶的例子here。如果这不是练习的要求,我将不会使用SwingWorker进行编程

1 个答案:

答案 0 :(得分:0)

您取消并表示您可能会打扰。

但请查看您的doInBackground代码:

@Override
protected Void doInBackground() throws Exception {
     while(true)
    {
        System.out.println("Runing" + this.index);
        move();
        if(this.x < 40) this.x = 40;
        if(this.x > PlayField.width - 40) this.x = (PlayField.width - 40);
        if(this.y < 40) this.y = 40;
        if(this.y > PlayField.height - 40) this.y = (PlayField.height - 40);
         try {
             Thread.sleep(200);
         } catch (InterruptedException ex) {
             Logger.getLogger(Robot.class.getName()).log(Level.SEVERE, null, ex);
         }
    }
}

我们看到您通过将InterruptedException记录在ctach块中(它清除了线程上的中断状态)来响应中断,然后轻松地继续循环。当然,这不会停止线程。

尝试响应线程的中断状态:

@Override
protected Void doInBackground() throws Exception {
    while(!Thread.currentThread().isInterrupted())   // break out of the loop onc ethe thread is interrupted
    {
        // ... omitted for brevity

         try {
             Thread.sleep(200);
         } catch (InterruptedException ex) {
             Thread.currentThread().interrupt();   // catching the exception clears the interrupted state, so we reset it, to break out of the loop.
         }
    }
}