【问题标题】:java.lang.OutOfMemoryError Unable to create new native threadjava.lang.OutOfMemoryError 无法创建新的本地线程
【发布时间】:2014-04-05 12:12:49
【问题描述】:

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

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

我知道使用多个 JFrame 是不好的做法,但我不认为重新创建一个全新的 Java 卡或选项窗格/对话框有什么意义。我还决心创建一个变通方法来让事情正常工作。

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

这是代码。异常指向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());

【问题讨论】:

    标签: java swing timer jtable global-variables


    【解决方案1】:

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

    一个大问题

    更好。

    您正忙于在 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 访问。

    简而言之;这段代码几乎没有没有错误。

    【讨论】:

    • 哈哈哎呀。我刚刚学到了一些新东西。好的,所以dowhile是一个大脑错误,我现在明白了。我对 javax.swing.Timer 类不太了解。我的编码基于互联网上的示例。我删除了 java.util.Timer 并用 javax.swing.Timer 替换它,但现在 IDE 给了我错误。我想它和我一起回到了javadocs......谢谢,尽管指出编码是正确的:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    相关资源
    最近更新 更多