2

検索中のサーバーの過負荷を軽減するために、キーボード入力の遅延を提供します。

使用例:
1.ユーザーが記号を入力する
2.記号を入力する間の遅延が1 秒未満の場合、その検索すぐには実行されず、最後に記号を入力した後の遅延が > 1 秒の場合は待機します
3.記号を入力する間の遅延が> 1 秒の場合、その検索は実行されますすぐに

JSE またはモバイル Java (Blackberry) にベスト プラクティスはありますか?

こういう場合はTimerTaskTimer APIを使えばいいみたいですね。

4

2 に答える 2

2

Java並行性聖書によると「実際のJava並行性」

...タイマーにはいくつかの欠点があり、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 を使用します。ルールに追加の変更をお勧めします。リクエストが少なくとも 1 秒間隔で配置されていることを確認してください。ただし、ユーザーが入力を 1 秒停止するまで待たないでください。代わりに、タイムアウトが切れるとすぐに、その時点の入力フィールドの状態で新しいリクエストを発行します。ユーザーは入力の途中かもしれませんが、アプリでのユーザー エクスペリエンスはより滑らかで応答性が高くなります。

于 2012-04-15T16:05:10.417 に答える