从匿名内部" runnable"内部调用方法类。这是不好的做法吗?

时间:2016-08-28 01:49:28

标签: java multithreading

首先,让我说,至少可以说,我不是世界上经验丰富的Java程序员。

当谈到像互联网访问这样的时间关键行为时,我开始经常使用下面的代码。这样,我可以在独占线程中运行任何方法。有时,我甚至会在第一个被调用的方法中调用其他方法。我假设,它们都在同一个线程中运行。如果我错了,请纠正我。

pingItem.addActionListener(event -> //listener of a JButton
{
    new Thread( new Runnable(){
        @Override
            public void run(){
            /*
             * some code...
             */
            showOnlineState(); //=> private static void showOnlineState()
        }
    }).start();
});

这真的很好用,而且使用起来非常简单。但是如果一个帖子被卡住了,那我就有点担心了#34;或者其他的东西。由于它是一个匿名课程,我不知道如何检查它和#34; .isAlive"或者如何阻止它。

我应该避免像这样编码吗?这是不良做法"?

3 个答案:

答案 0 :(得分:1)

我想说设计可以改进:

  1. 将新并发包中的Executor类更喜欢JDK 1.0 Thread。
  2. 如果您传入Runnable,则可以轻松更改操作。使用内部类需要您编辑和重新部署代码以进行更改。
  3. 当您将其设置为关闭时,意识到该线程处于操作系统的控制之下。你无法阻止它。您可以设置超时。

答案 1 :(得分:0)

  

我有点担心一个线程是否被“卡住”或什么东西。由于它是一个匿名类,我不知道如何使用“.isAlive”或如何阻止它来检查它。

如果你想对线程做一些事情(例如,检查它的状态),那么你必须在某处保持对它的控制Thread对象的引用。

Thread myBackgroundThread = new Thread( new Runnable(){
    @Override
        public void run(){
        doSomethingUseful(...);
    }
});
myBackgroundThread.start();

...

if (myBackgroundThread.getState() == Thread.State.TERMINATED) {
   doSomethingAboutIt(...);
}
  

从匿名内部“runnable”类中调用方法。这是不好的做法吗?

没有。如果您需要多行代码来完成创建线程的工作,那么将其分解为方法将是不好的做法。

答案 2 :(得分:0)

确实有理由做这样的事情,但在这种情况下重新考虑,因为以这种方式使用线程是浪费。

您正在使用swing,并且应该快速处理按钮单击,并且不应该在事件处理线程上进行长时间的处理。

因为它存在SwingUtilities.invokeLater(Runnable)SwingWorker。看看那个。事件处理线程也是重新绘制的地方。

然后大多数线程都没有必要。仍然。由于物理线程有限,因此线程池可能很有用,ExecutorService。 请查看FutureTask的示例。

基本上,当某些东西抛出异常时,线程没有问题。但是系统行为,死锁,资源存在缺陷:启动线程的线程。简单的架构有助于构建可靠的软件。你可以让Action childs扩展AbstractAction,以便在menues和button中重复使用。

<强> 精化

actionPerformed部分可以放入Action(界面)。 JButton has a constructor就是这样。最好的一个来自AbstractAction。这是一种纯粹的体系结构分离,而不是添加匿名的ActionListener。它对系统行为没有影响,但现在你可以在Action而不是JButton上执行setEnabled,并在菜单中添加Action。

它具有相同的actionPerformed事件处理。您也可以在JMenuItem中重用相同的操作。 Swing集中使用这些操作。

private Action openAction = new AbstractAction() {
    {
        putValue(..., ...); // Here you can set icon, button text,
        putValue(..., ...); // shortcuts and such.
        putValue(..., ...);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        EventQueue.invokeLater(() -> {
            ...
        });
    }
}

JButton openButton = new JButton(openAction);
JMenuItem openMenuItem = new JMenuItem(openAction);

... openAction.setEnabled(false);

对于简短但不是即时的任务,还可以在actionPerformed中弹出文件选择器或此类用法:

SwingUtilities.invokeLater(() -> {
    ...
});

对于较长时间的操作,在后台工作,可以使用SwingWorker,其他地方存在更好的示例。它实现了RunnableFuture,Future就是您的要求:

  • 以等待的方式获得结果
  • 得到超时
  • 取消
  • isCancelled
  • isDone