java.lang.OutOfMemoryError 无法创建新的 native 线程

标签 java swing timer jtable global-variables

(在 NetBeans/Java 中工作)我使用一个按钮从外部源检索值,一切正常,但有一些小问题,然后我开始遇到 java.lang.OutOfMemoryError: unable to create新的 native 线程异常

此应用程序将外部值写入 JTable。此外部值是其他位置的公共(public)变量

我知道使用多个 JFrames 是不好的做法,但我看不出重新创建一个全新的 Java Card 或 Option Pane/Dialog 有什么意义。我还决心创建一个变通办法来使它正常工作。

可能是什么原因造成的,我该如何解决?

这是代码。异常指向 Timer timer = new Timer();

String username;
String password;

//...

final Apps.UserManager.NewUser newUser = new Apps.UserManager.NewUser();
newUser.setVisible(true);
newUser.requestFocus();

newUser.suVftrun = 0;

int delay = 10000; // delay for 10 sec.
int period = 1000; // repeat every sec.

do{
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
            int bcol1 = model.getColumnCount();
            int bcol2 = model.getRowCount();

            username = newUser.u2ftrun;
            password = newUser.p2ftrun;

            System.out.println(newUser.u2ftrun);
            System.out.println(newUser.p2ftrun);

            try {
                String tRecord1 = (String) jTable1.getValueAt(bcol1, bcol2);
                if (newUser.suVftrun == 1) {
                    if (!username.equals(null)) {
                        if (!tRecord1.equals(username)) {
                            model.addRow(new Object[]{username, password});
                            this.cancel();
                        } else {
                            System.out.println("Same Data");
                        }
                    } else {
                        System.out.println("No Data Received!");
                    }
                } else {
                    System.out.println("User hasn't been created yet");
                }
            } catch (Exception ex) {
                System.out.println("No values in table. Trying alternative");
                try {
                    if (newUser.suVftrun == 1) {
                        if (!username.equals(null)) {
                            try {
                                model.addRow(new Object[]{username, password});
                                this.cancel();
                            } catch (Exception e) {
                                System.out.println("Repeating...");
                            }
                        } else {
                            System.out.println("No Data Received!");
                        }
                    } else {
                        System.out.println("User hasn't been created yet");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }, delay, period);
} while (newUser.isVisible());

最佳答案

您有一个大问题。等等,这还不够大:

一个大问题

更好。

您正忙于等待 do 循环并每次都启动一个新的 Timer:

do {
    Timer timer = new Timer();
    //some other stuff
} while (newUser.isVisible());

这导致创建了数千(数百万?)个 Timer 实例,每个实例都有自己的 Thread

  1. 从不忙等
  2. 不要创建数以千计的 Timer 实例

此外,您正在使用 java.util.Timer不是 javax.swing.Timer这意味着最终操作不会在 EDT 上执行。

这违反了 Swing 线程策略。 Swing 对象,rare case 除外,不是线程安全的,应该只能从 EDT 访问

简而言之;这段代码几乎没有什么不是的错误。

关于java.lang.OutOfMemoryError 无法创建新的 native 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22880742/

相关文章:

java - 将对象放入 JComboBox 中

java - 在 netbeans 中单击“运行”时不显示 Jpanel

java - 如何在 Java/GWT 中经过一段时间后隐藏弹出窗口

c - 在C中使用定时器

java - 基于参数的通用转换

java - 使用 JXL 访问 Excel 中超过 256 列

java - 由空格和可选引号分隔的 csv 文件的正则表达式

java - HIbernate Annotation 在 MySQL 中自动生成表

java - 如何找出屏幕上显示的java组件

javascript - 如何在幻灯片中设置计时器以显示所选内容?