从 ScheduledExecutorService 中删除 Runnable

2024-05-01

情况是这样的,代码如下

用户填写 3 个字段并按“添加”按钮 => 创建一个 ToDoBean 并将其添加到 ToDoModel(扩展 AbstractTableModel) 并使用模型中 ToDoBean 的索引创建一个 Runnable。 Runnable 通过 ScheduledExecutorService 立即启动。

Runnable 的目标是递减 int 直到它达到零。

一切正常。

现在用户还可以在 JTable 中选择一行并按“Remove”按钮从列表中删除 ToDoBean。

我的问题是:当我删除该 bean 时,它看起来也从 ScheduledExecutorService 中删除了。为什么?如何? 事实上,这正是我所需要的,但我想了解其机制。 谢谢

代码:

package demo.todolist;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class ToDoFrame extends javax.swing.JFrame {

    private final static int POOL_SIZE = 10;
    private ToDoModel model = new ToDoModel();
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(POOL_SIZE);           

    /** Creates new form ToDoFrame */
    public ToDoFrame() {
        initComponents();
    }

    private ToDoBean createToDoBean() {
        return new ToDoBean(jTextField1.getText(), jTextField2.getText(), Long.valueOf(jTextField3.getText()));
    }

    private void addToList(ToDoBean toDoBean) {
        model.addToDoBean(toDoBean);
        scheduledExecutorService.schedule(new UpdateRunnable(model.getRowCount() - 1), 0,TimeUnit.SECONDS);
    }

    private class UpdateRunnable implements Runnable {

        private int index;

        public UpdateRunnable(int index) {
            this.index = index;
        }

        @Override
        public void run() {
            System.out.println("Task for index " + index + " started");
            while (model.getToDoBeanAt(index).getDelay() > 0) {
                try {
                    Thread.sleep(10000);
                    model.decreaseBeanAt(index);
                    System.out.println("Delay decreased at index " + index);

                } catch (InterruptedException ex) {
                    Logger.getLogger(ToDoFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            System.out.println("Task for index " + index + " ended");
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {
        GridBagConstraints gridBagConstraints;

        jLabel1 = new JLabel();
        jLabel2 = new JLabel();
        jLabel3 = new JLabel();
        jTextField1 = new JTextField();
        jTextField2 = new JTextField();
        jTextField3 = new JTextField();
        jButton1 = new JButton();
        jScrollPane1 = new JScrollPane();
        jTable1 = new JTable();
        jButton2 = new JButton();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridBagLayout());

        jLabel1.setText("Name :");
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jLabel1, gridBagConstraints);

        jLabel2.setText("Description :");
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jLabel2, gridBagConstraints);

        jLabel3.setText("Delai (seconds) :");
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jLabel3, gridBagConstraints);

        jTextField1.setText("my name ");
        jTextField1.setMinimumSize(new Dimension(50, 25));
        jTextField1.setPreferredSize(new Dimension(80, 27));
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jTextField1, gridBagConstraints);

        jTextField2.setText("some description");
        jTextField2.setMinimumSize(new Dimension(145, 25));
        jTextField2.setPreferredSize(new Dimension(145, 27));
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jTextField2, gridBagConstraints);

        jTextField3.setHorizontalAlignment(JTextField.TRAILING);
        jTextField3.setText("5");
        jTextField3.setMinimumSize(new Dimension(25, 25));
        jTextField3.setPreferredSize(new Dimension(25, 27));
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jTextField3, gridBagConstraints);

        jButton1.setText("Add");
        jButton1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        getContentPane().add(jButton1, new GridBagConstraints());

        jScrollPane1.setMinimumSize(new Dimension(280, 150));
        jScrollPane1.setPreferredSize(new Dimension(280, 275));

        jTable1.setModel(model
        );
        jScrollPane1.setViewportView(jTable1);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 3;
        getContentPane().add(jScrollPane1, gridBagConstraints);

        jButton2.setText("Remove");
        jButton2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        getContentPane().add(jButton2, gridBagConstraints);

        pack();
    }// </editor-fold>

    private void jButton1ActionPerformed(ActionEvent evt) {
        addToList(createToDoBean());
    }

    private void jButton2ActionPerformed(ActionEvent evt) {
        int rowIndex = jTable1.getSelectedRow();
        model.removeToDoBeanAt(rowIndex); 
        /*
         * the ToDoBean is removed from the list
         * the table is updated
         * the scheduledExecutorService is also updated ... why?
         */
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ToDoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ToDoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ToDoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ToDoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ToDoFrame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private JButton jButton1;
    private JButton jButton2;
    private JLabel jLabel1;
    private JLabel jLabel2;
    private JLabel jLabel3;
    private JScrollPane jScrollPane1;
    private JTable jTable1;
    private JTextField jTextField1;
    private JTextField jTextField2;
    private JTextField jTextField3;
    // End of variables declaration
}

包 demo.todolist;

导入java.util.ArrayList;导入java.util.List;进口 javax.swing.table.AbstractTableModel;

公共类 ToDoModel 扩展 AbstractTableModel {

protected List<ToDoBean> list = new ArrayList<ToDoBean>();
private final static String[] columns = {"Name", "Description", "Remaining"};
private final static Class[] columnsClass = {String.class, String.class, Long.class};
public final static int[] columnWidths = {80, 150, 50}; // 280

public ToDoModel() {
}

public ToDoModel(List<ToDoBean> list) {
    super();
    this.list = list;
}

@Override
public Class getColumnClass(int columnIndex) {
    return columnsClass[columnIndex];
}

@Override
public int getRowCount() {
    return list.size();
}

@Override
public int getColumnCount() {
    return columns.length;
}

@Override
public String getColumnName(int col) {
    return columns[col];
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    ToDoBean result = list.get(rowIndex);
    switch (columnIndex) {
        case 0:
            return result.getName();
        case 1:
            return result.getDescription();
        default:
            return result.getDelay();
    }
}

@Override
public void setValueAt(Object obj,int rowIndex, int columnIndex) {
    ToDoBean result = list.get(rowIndex);
    switch (columnIndex) {
        case 0:
            result.setName((String) obj);
            break;
        case 1:
            result.setDescription((String) obj);
            break;
        default:
            result.setDelay((Long) obj);
    }
    list.set(rowIndex, result);
    this.fireTableCellUpdated(rowIndex, columnIndex);
}

public void addToDoBean(ToDoBean w) {
    list.add(w);
    fireTableDataChanged();
}

public void addToDoBeanList(List l) {
    list.addAll(l);
    fireTableDataChanged();
}

public ToDoBean getToDoBeanAt(int row) {
    return list.get(row);
}

public ToDoBean removeToDoBeanAt(int row) {
    ToDoBean pos = list.remove(row);
    fireTableDataChanged();
    return pos;
}

public long decreaseBeanAt(int rowIndex) {
    ToDoBean result = list.get(rowIndex);
    long remaining = result.getDelay();
    result.setDelay(--remaining);
    this.fireTableCellUpdated(rowIndex, 2);
    return remaining;
} }

包 demo.todolist;

公共类 ToDoBean {

private String name;
private String description;
private long delay;

public ToDoBean(String name, String description, long delay) {
    this.name = name;
    this.description = description;
    this.delay = delay;
}

public ToDoBean() {
}

public long getDelay() {
    return delay;
}

public void setDelay(long delay) {
    this.delay = delay;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public void decrease() {
    delay--;
} }

我偶然发现了你的问题,我有一个很好的解决方案。用一个调度线程池执行器 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html。它将允许您安排任务并在不再需要时将其删除。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 ScheduledExecutorService 中删除 Runnable 的相关文章

  • 何时在 SQL 语句中使用单引号?

    我知道当我处理 TEXT 类型的数据时应该使用它 我猜是那些回退到 TEXT 的数据 但这是唯一的情况吗 Example UPDATE names SET name Mike WHERE id 3 我正在用 C 编写 SQL 查询自动生成
  • 我可以使用什么 C++ 库在 Windows 上将 PDF 转换为图像?

    我正在开展一个需要分析图像的项目 这些图像的主要来源是网络摄像头 但最近我们被要求添加对上传文件和扫描仪的支持 这在大多数情况下都很好 只是他们希望我们能够使用 PDF 格式的文档 我需要一个原始像素位图进行处理 在 Mac 上 我可以使用
  • 如何从指纹扫描仪获取输入并保存[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在使用 Android Marshmallow 和 Moto G4 以及一台设备进行测试 我想创建一个应用程序 它将接受指纹输入并
  • bet365 网站上 Selenium 的 Chrome 驱动程序陷入灰屏

    当我尝试使用 Chrome 驱动程序和 Selenium 打开 bet365 网站时出现灰屏 var driver new ChromeDriver driver Navigate GoToUrl https www bet365 it 我
  • 如何构建具有多个子站点地图的站点地图?

    我在用 MVC4 MvcSiteMapProvider v3 2 1 需要能够升级到v4 我的问题是应用程序很大 我想模块化应用程序并使模块可插拔 由于站点地图已经很大 我想让站点地图也变得可插拔 有没有办法在应用程序启动时使用根站点地图从
  • 使用 Android 手机在空中绘画

    我正在开发一个用 Android 手机在空中画画的应用程序 当我的手机移动时 借助加速度计 我检索了每个轴 ax ay az 上的加速度 我感兴趣的是 x y z 根据我在论坛和一些教程中读到的内容 两次积分加速会产生巨大的错误 那么 对于
  • WCF WebGetAttribute 与 WebInvokeAttribute

    WebGetAttribute 只是 Method GET 的 WebInvokeAttribute 的语法糖吗 或者有根本的区别吗 您立即观察到 WebGet 和 WebInvoke 非常相似 这与事实相差不远 正如您已经说过的 WebG
  • 在 R 中的轴标签中绘制表情符号/自定义图像

    我正在尝试在 R 中绘制表情符号和自定义图像作为 X 轴的标签 我读过类似的帖子并且问题 https stackoverflow com questions 47730589 plot emojis emoticons in r with
  • 如何在弹性搜索中生成多个布尔查询的查询

    我想使用 spring 框架在 elasticsearch 中动态生成多个布尔运算的查询 我在elasticsearch中的数据就像 masterID
  • pip install 找不到包,但 pip search 找到

    我想安装hdbcli https pypi org project hdbcli 包 SAP HANA 连接器 当我搜索时pip正在找到该包 但是当我想安装它时 pip找不到包裹 指定当前包也不会产生任何结果 pip install hdb
  • 使用霍夫曼代码压缩文件的步骤

    我知道有很多涉及霍夫曼代码的问题 包括我自己的另一个问题 但我想知道实际编码文本文件的最佳方法是什么 减压看似微不足道 遍历树 在 0 处向左 在 1 处向右 打印字符 但是 如何进行压缩呢 以某种方式将字符的位表示存储在树的节点中 每次遇
  • 使用 R 连接到 SSAS 多维数据集

    是否可以使用 R 查询 SQL Server Analysis Services 多维数据集 我在不同的外部服务器上有这个多维数据集 并且我正在我的计算机上工作 但我使用我的域帐户在服务器上拥有管理员权限 简而言之 我想创建一个分析服务解决

随机推荐

  • javascript检测字符串是否只包含unicode表情符号[重复]

    这个问题在这里已经有答案了 我正在使用以下函数来替换字符串中的表情符号 并且效果很好 function doEmoji s var ranges ud83c udf00 udfff U 1F300 to U 1F3FF ud83d udc0
  • Maven 2 checkstyle 插件版本 2.5 - configLocation 问题

    我在 maven 2 中使用 checkstyle 插件 我现在想要将我的配置文件从默认文件切换为 a 在线文件 或 b 本地文件 我尝试了以下两件事 但都不起作用 有什么建议么 A 本地文件 直接位于我的项目文件夹中的 pom xml 旁
  • 如何从 Android 设备检索 RCS 消息

    我如何在android中检索RCS消息 我可以使用 contentproviders 检索 SMS MMS 是否有适用于 Android 的 RCS 消息传递的 URI 我发现我的设备有这个 contentprovider 可用 所以我尝试
  • 如何在 NSBundle 中从 Assets.car(xcassets 的编译版本)加载图像?

    简而言之 如何从已编译的图像中加载图像Assets car在一个NSBundle 完整版本 我正在转换一套应用程序以供使用CocoaPods 每个应用程序都依赖于一个名为Core Core包括代码文件 xib文件 以及几个xcasset f
  • powershell 中的 PsObject 数组

    这是我的代码 a for i 0 i lt 5 i item New Object PSObject item Add Member type NoteProperty Name Col1 Value data1 item Add Memb
  • 如何通过 WinDBG 在 Dump 中查找非托管内存中的内容

    我在 WinDbg 命令中运行转储文件 地址 摘要 我的结果是这样的 Usage Summary RgnCount Total Size ofBusy ofTota Free 3739 7ff5 dbbae000 127 960 Tb 99
  • 如何更改prestashop中订单确认电子邮件模板的内容?

    我想更改订单确认电子邮件模板的内容 前提是已订购特定产品 有什么解决办法吗 您可以在mails language order conf html txt 中找到电子邮件订单确认的通用模板 mails languages order conf
  • IIS7 中的 DefaultAppPool 和经典 .NET AppPool 有什么区别?

    我在 IIS 中遇到超时问题 在 web config 中 会话超时设置为 60 分钟 但 20 分钟后会话结束 此问题仅在IIS7中出现 在IIS5中不会出现 经过一番调查 我发现这是由于应用程序池超时造成的 如果应用程序池有 20 分钟
  • 如何声明具有类型并实现协议的变量?

    我的应用程序有一个详细视图控制器协议 声明它们必须有一个viewModel财产 protocol DetailViewController class var viewModel ViewModel get set 我还有一些实现该协议的不
  • Facebook Messenger Bot:视频附件的大小?能有多大?

    至少在此处的文档中没有说明通过 Facebook Messenger 发送视频附件时所需的大小和格式 https developers facebook com docs messenger platform send api refere
  • 如何将变量传递到 Azure 数据工厂 REST url 查询字符串

    我是 Azure 数据工厂的新手 我有一个链接到 REST api 的源数据集 该 API 的 url 有一个查询字符串 我有一个将数据从 REST 复制到数据库的活动 但我必须在查询字符串中传递不同的值 并对不同的值运行相同的活动 如何在
  • 使用 jQuery 获得第一堂课和最后一堂课

    可能是新手问题 我有这样的代码行 div class template active 我需要为自己准备每一堂课 我尝试了这段代码 this attr class 从该代码中我得到 模板处于活动状态 我需要的是一个带有 template 的字
  • Java 中的 lambda 目标类型和目标类型上下文是什么意思?

    我正在阅读 Herbert Schildt 的 Java 完整参考 中关于 lambda 的一章 其中有很多对 lambda 目标类型 和 目标类型上下文 的引用 函数式接口定义了目标类型的一个 拉姆达表达式 这里有一个关键点 只能使用 l
  • 如何为webpack使用自己的jade文件?

    我是 webpack 的新手 并试图弄清楚如何在 webpack dev server 中使用我自己的 html 文件以及我的 webpack 构建 在我的 app js 中我有 require jade index jade 但这并不意味
  • 通过页面打开 mysql 连接是完全鲁莽的吗?

    当查询数据库时 是否会感到极度偏执 每次必须完成新查询时 我都会打开和关闭 mysql 连接 我担心 尤其是启用 ajax 的页面 这会导致性能大幅下降 我应该继续使用此方法 还是至少在每个页面 而不是每个查询 中打开和关闭连接一次 顺便说
  • 如何在vala中使用gettext?

    当我尝试在 vala 中使用 gettext 时 我没有收到来自 vala 的错误或警告 但我从 c 编译器收到以下错误 usr include glib 2 0 glib gi18n lib h 29 2 error error You
  • 单击时显示数组中的下一个图像

    我正在努力设置可以通过屏幕箭头点击的图像 目前 我的图像全部通过循环和数组显示 我已经能够进行设置 以便当您将鼠标悬停在小图像预览上时 主图像将更改为该图像 也就是说 您可以将鼠标悬停在它们上以查看更大的版本 我的数组位于 mongo 模型
  • Unity构建错误

    所以我制作了我的游戏并尝试构建它 我收到一些对我来说毫无意义的错误 这是错误 UnityEditor BuildPlayerWindow BuildMethodException 2 个错误 在 UnityEditor BuildPlaye
  • C++ static constexpr 成员在类外重新声明

    对于以下代码 为什么 main 中的第一个案例无需重新声明 Foo bar 就可以正常工作 而带有该函数的第二个案例则需要它 struct Foo static constexpr int bar 30 Declaration of Foo
  • 从 ScheduledExecutorService 中删除 Runnable

    情况是这样的 代码如下 用户填写 3 个字段并按 添加 按钮 gt 创建一个 ToDoBean 并将其添加到 ToDoModel 扩展 AbstractTableModel 并使用模型中 ToDoBean 的索引创建一个 Runnable