java - 无法取消 WorkerThread 。取消函数什么时候执行,仍然执行

标签 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 类(class)

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 进行编程

最佳答案

您取消,并表明您可以打断。

但是看看你的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);
         }
    }
}

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

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

@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.
         }
    }
}

关于java - 无法取消 WorkerThread 。取消函数什么时候执行,仍然执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58417381/

相关文章:

java - Java 中 Thrift 的异步请求

java - 为什么这不起作用 - 使用 Junit 的参数化数据对同步方法进行单元测试?

python - 遇到同时连接到多个设备的多线程问题

java - setDefaultButton 未按预期工作

java - 如何在 JTable 中添加 JCombobox 并在 JTable 内触发其操作?

java - 使用 Guice 注入(inject) Swing 组件的最佳实践?

java - 通过单击菜单项来调用java中的函数

java - 在java中对数组进行排序

c++ - 将写锁降级为读锁时 TMultiReadExclusiveWriteSynchronizer 的行为

java - 将值添加到 vector 时抛出 NullPointerexception