Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> GUI блокируется сторонним потоком, взаимодействие потоков с потоком GUI  
:(
    Опции темы
_Y_
Дата 16.11.2008, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



Знаю что тема старая-затасканная, не бейте. В очередной раз столкнулся с блокировкой GUI при выполнении сложных рассчетов, хотя рассчеты выполняются в отдельном потоке. Стал искать ошибку. Не нашел пока. Но зато натолкнулся на такой странный феномен. Это два простых тест класса. Первый это GUI. Он просто показывает ничем друго другу не обязанные JLabel и JButtonJButton считает сколько раз на него нажали (ну надо же ему что-то делать):

Код

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class SimpleTestsGUI extends JFrame {

    public static SimpleTestsGUI jFrame;
    public static JLabel label = new JLabel("---");
    
    private JButton button;
    
    public static void main(String[] args) {
        jFrame = new SimpleTestsGUI();    
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setSize(500, 350);
        jFrame.setVisible(true);    
        
        BusyThread busyThread = new BusyThread(label);
        busyThread.run();
    }
    
    //CONSTRUCTOR
    
    public SimpleTestsGUI(){
        
        button = new JButton("0");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent evt){
                button.setText("" + (Integer.parseInt(button.getText()) + 1));
            }});
        
        this.add(button);
        
        this.add(label, BorderLayout.NORTH);
    }
}


Второй класс иммитирует тяжелые рассчеты, посылая при этом их результаты в JLabel и на консоль:

Код

import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class BusyThread extends Thread {
    
    private JLabel label;
    private ArrayList<Double> list = new ArrayList<Double>();
    private double sum;
    private int count = 0;

   //CONSTRUCTOR
    
    public BusyThread(JLabel lb){
        label = lb;
        this.setPriority(Thread.MIN_PRIORITY);
    }
    
    public void run() {
     
     //Иммитация тяжелых рассчетов
 
     while(true){
         sum = 0;
         for(Double d : list) sum += d;
         
         if(sum > 100d || list.size() > 200) list = new ArrayList<Double>();
         
         list.add(new Double(Math.random()));
         
         if(++count >= 10000){
             
             count = 0;
             
                //Вывод "резултатов"

                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                     label.setText("" + sum);
                     System.out.println(sum); //Этот оператор все и тормозит
                    }
                });                   
         }
      }
    }    
}


Работа второго класса очень ощутимо подвешивает GUI, хотя и не завешивает полностью. Если же закомментировать во втором классе строку №41 System.out.println("" + sum); то ничего больше не подвисает.

Ну очень интересно чем это обусловлено.

Это сообщение отредактировал(а) _Y_ - 16.11.2008, 19:45


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
powerOn
Дата 16.11.2008, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 31
Всего: 159



Так вы же сами загружаете EDT вот это операцией:

Код

SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                     label.setText("" + sum);
                     System.out.println(sum); //Этот оператор все и тормозит
                    }
                }); 




Это сообщение отредактировал(а) powerOn - 16.11.2008, 21:31


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
_Y_
Дата 16.11.2008, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



Цитата(powerOn @ 16.11.2008,  21:31)
Так вы же сами загружаете EDT...

Был бы очень благодарен за подробности. Что при этом конфликтует и почему? А как быть?


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Vurn
Дата 17.11.2008, 04:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 24.5.2007

Репутация: нет
Всего: 3



На каждый оператор, в том числе и System.out.println(), требуется свое время на выполнение, большое или маленькое. println() работает достаточно медленно по сути, и придерживает поток в итоге. Избавиться от задержек можно накапливая результат в StringBuffer, вываливая на экран содержимое этого буффера из другого потока время от времени.
PM MAIL   Вверх
_Y_
Дата 17.11.2008, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



Vurn, в том-то и дело, что этот оператор не тормозит программу, а именно подвешивает GUI. При этом на консоль ничего не выводится, просто GUI висит довольно продолжительное время.

За решение спасибо, но вопрос не как решить задачу (она-то как раз простая, но и никому не нужная). Вопрос почему подвисает GUI, что конфликтует, в чем ошибка?


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
ivg
Дата 17.11.2008, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 4
Всего: 81



Цитата(_Y_ @  18.11.2008,  01:41 Найти цитируемый пост)
Вопрос почему подвисает GUI

Это то как раз понятно, метод run() (строки 39-42) выполняется Event Dispatch Thread'ом, и если он будет выполняться относительно долго то GUI будет тормозить. Непонятно почему System.out.println() тормозит. У меня (JVM 1.6.0_07 Sun, win32, XP SP2) - разницы не вижу. Вытащите System.out.println(sum); из под SwingUtilities.invokeLater(...); да и всё. И кстати busyThread.start() наверно, а не run(); ?
PM MAIL   Вверх
Vurn
Дата 18.11.2008, 07:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 24.5.2007

Репутация: нет
Всего: 3



Я бы рекомендовал, по сути, никогда не использовать System.out.println() внутри циклов. Вместо этого накапливал бы логи в StringBuffer/StringBuilder и при нужных условиях писал их куда мне надо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0734 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.