что является рекомендуемой альтернативой опросу с использованием цикла while - PullRequest
1 голос
/ 01 декабря 2011

Так что это мой код, который запрашивает изменение в модели моего приложения.

    Thread refreshThread = new Thread(new Runnable() {

        public void run() {

            while(true)
            {                       
                if(TasksManager.isDirty())
                {
                    TasksManager.refreshTasks(true);
                    panel.repaint();
                }
            }
        }
    });
    refreshThread.start();  

Сейчас это огромная загрузка процессора.Вот разбивка того, что происходит.

  1. TaskManager понимает, что было добавлено что-то новое.
  2. TaskManager помечает себя как грязный.
  3. Когда мои потоки обновлений обнаруживают, что он грязный, он немедленно выполняет обновлениена модели и панели дисплея.
  4. В конце RefreshTasks () модель снова помечается как чистая.

Я не хотел, чтобы TaskManager запускал обновлениепоскольку он не содержит ссылок на панель просмотра.

Одна из идей, которые у меня есть, - это использовать условие .await ().TaskManager может сигнализировать о состоянии, когда оно было помечено как грязное.Но я вижу, что Замки и Условия идут рука об руку.Можно ли использовать Условие, не получая Блокировку в начале функции?

Ответы [ 2 ]

4 голосов
/ 01 декабря 2011

Вы можете использовать wait() и notifyAll(), чтобы избежать высокой загрузки ЦП:

private final Object dirtyLock = new Object();

Thread refreshThread = new Thread(new Runnable() {
    public void run() {
       while(true){
           synchronized(dirtyLock){
               dirtyLock.wait(); // Send this thread to sleep until dirtyLock is unlocked                       
           }
           TasksManager.refreshTasks(true);
           panel.repaint();
        }
    });
refreshThread.start(); 

// When your TaskManager becomes dirty, do the following
public void changeToDirty(){
    TaskManager.setDirty(true);
    synchronized(dirtyLock){
           dirtyLock.notifyAll(); 
           // this will release the refresh thread which will repaint and then go to sleep
     }
}
4 голосов
/ 01 декабря 2011

Почему вы не используете слушателей для этого?

Если у вас есть простой подкласс TasksManager с именем ContentChangedListener. Затем вы можете объявить материал panel.repaint () в слушателе, который зарегистрирован в TasksManager от всех, кого это интересует. Многие слушатели могут быть зарегистрированы по мере необходимости.

Вместо кода, который помечает TasksManager как грязный, замените его циклом, чтобы уведомить всех слушателей об изменении.

Преимущество этого решения заключается в том, что не требуется другой поток или цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...