2

为了减少搜索时的服务器过载,我将为键盘输入提供延迟。

用例:
1.用户输入符号
2.如果输入符号之间的延迟< 1 秒则不会立即执行搜索,并且在最后输入符号后的延迟> 1 秒时等待
3.如果输入符号之间的延迟> 1 秒,则执行搜索立即地

JSE 或移动 Java(黑莓)中是否有最佳实践?

看起来我应该在这种情况下使用TimerTaskTimer API。是吗?

4

2 回答 2

2

根据Java并发圣经' Java concurrency in practice '

... Timer 有一些缺点,ScheduledThreadPoolExecutor 应该被认为是它的替代品。

因此,我会做类似这个例子的事情:

public class DelayedSearch extends JFrame {
    public DelayedSearch() {
        final JPanel panel = new JPanel(new BorderLayout());
        final JTextField field = new JTextField(30);
        panel.add(field, BorderLayout.NORTH);
        final JLabel status = new JLabel(" ");
        panel.add(status, BorderLayout.SOUTH);
        this.add(panel);
        this.pack();
        final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        field.addKeyListener(new KeyAdapter() {
            private ScheduledFuture<?> scheduled;
            @Override
            public void keyTyped(KeyEvent e) {
                if (scheduled != null) scheduled.cancel(false);
                scheduled = executor.schedule(new Runnable() {
                    @Override
                    public void run() { // Perform search here. Just set status for demo.
                        status.setText("Search: " + field.getText());
                    }
                }, 1, TimeUnit.SECONDS);
            }
        });
    }
    public static void main(String[] args) {
        new DelayedSearch().setVisible(true);
    }
}

注意:我正在从 EDT 以外的线程更新状态,这是非法的,但你明白了。

编辑:基于下面的精彩评论(谢谢!)Timer将在这个简单的情况下工作,并且它使使用守护线程变得容易(尽管它确实存在引发异常的任务的问题,如书中所述)。为此,请按如下方式替换上面的执行器和侦听器:

        ...
        final Timer timer = new Timer(true); // use daemon thread.
        field.addKeyListener(new KeyAdapter() {
            private TimerTask task;
            @Override
            public void keyTyped(KeyEvent e) {
                if(task != null)task.cancel();
                task = new TimerTask() {
                    @Override
                    public void run() {
                        status.setText("Search: " + field.getText());
                    }
                };
                timer.schedule(task, 1000);
            }
        });
于 2012-04-15T16:48:18.760 回答
1

是的,使用 TimerTask。我建议对您的规则进行额外的更改:只需确保请求间隔至少一秒钟,但不要等到用户停止输入一秒钟后。相反,当超时到期时,会立即发出一个带有输入字段状态的新请求。用户可能正在打字,但他对您的应用程序的体验将更加流畅和响应迅速。

于 2012-04-15T16:05:10.417 回答