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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация потока, его приостановка и запуск 
V
    Опции темы
x3bytes
Дата 10.11.2006, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Beaver



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

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



Код

package testapp;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;


public class PicPanel extends JPanel implements Runnable{
    Image image;
    boolean mousePressed=false; //флаг показывающий когда клавиша мыши нажата
    
    JFrame pMain;
    public Thread thread = null; //Главный поток
    
    public PicPanel(String source, JFrame pM){
        String file = source;
        pMain = pM;
        try{
            image = super.getToolkit().getImage(this.getClass().getResource(file));
        } catch(Exception e){
            JOptionPane.showMessageDialog(this, e.getMessage());
            System.out.println(e.getMessage());
        }
        
        thread = new Thread(this);
    
    this.setCursor(new Cursor(Cursor.HAND_CURSOR));
    
    //Обработчики событий мыши
    this.addMouseListener(new MouseAdapter() {
        //Invoked when a mouse button has been pressed on a component.
        public void mousePressed(MouseEvent event) {
            mousePressed=true;
            int i=0;   
            thread.start();                        
            
        }
        
        //Invoked when a mouse button has been released on a component.
        public void mouseReleased(MouseEvent event) {
            mousePressed=false;
            
        }
        
        //Invoked when the mouse button has been clicked (pressed
        //and released) on a component.
        public void mouseClicked(MouseEvent e){}
        
        //Invoked when the mouse enters a component.
        public void mouseEntered(MouseEvent e){}
        
        //Invoked when the mouse exits a component.
        public void mouseExited(MouseEvent e){}
        
    });
    this.addMouseMotionListener(new MouseMotionListener() {
        //Invoked when the mouse cursor has been moved onto a component
        //but no buttons have been pushed.
        public void mouseMoved(MouseEvent event){
        }
        
        //Invoked when a mouse button is pressed on a component and then
        //dragged.
        public void mouseDragged(MouseEvent e) {
        }
    }
    );
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g = g.create();
    g.drawImage(image, 0, 0, this);
}

public void run() {
    thread = Thread.currentThread();
    for(int i=0;mousePressed==true;i++){
        pMain.setTitle("i = "+i);
    }
    thread = new Thread(this);
}

}


Здесь создаётся поток. Тоесть при нажатии на  JPanel у окна которое содержит этот JPanel начинает крутится счётчик в заголовке окна.
Грубо говоря пример эммуляции зажатия кнопки мыши на объекте(ведь в этом JPanel может быть рисованая кнопка)

Мой вопрос про оптимизацию потока. Вроде всё работает, но если подумать то когда мы не нажимаем на JPanel наш поток надо приостанавливать(зачем зря будет работать). Потом запуск реализуется коммандой start() и постоянно вызывается при нажатии мышки. Правильно ли это? Как я знаю надо только 1 раз вызывать start() при запуске потока.
Я пытался разобраться с wait() yield() и suspend() но чтот безрезультатно. Может ктот приведёт код правильного использования этих комманд?

Можно ли реализовать поток независимо от этого класса Runnable типа:
Код

Thread thread = new Thread(new Runnable(){
public void run(){
for(int i=0;mousePressed==true;i++){
            pMain.setTitle("i = "+i);
        }
}
});

так как если заменить этим кодом строчку 
Код

thread = new Thread(this);

то при повторном нажатии на JPanel выскочит ошибка 
at java.lang.Thread.start(Thread.java:571)
PM MAIL   Вверх
LSD
Дата 10.11.2006, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



1. Сделай так:
Код
  private final Object lock = new Object();
  private boolean fullStop = false;
  private boolean work = false;

  public void run()
  {
    while(!fullStop)
    {
      while(work)
      {
        //do work here
      }
      try
      {
        synchronized(lock)
        {
          lock.wait();
        }
      }
      catch(InterruptedException e)
      {
      }
    }
  }

когда тебе надо выполнить какую-то работу делаешь так:
Код
work = true;
synchronized(lock)
{
  lock.notifyAll();
}

когда закончишь:
Код
work = false;

когда необходимость выполнять действия отпадет вообще (окно будет закрыто, выход из приложения и т.п.):
Код
fullStop = true;
work = false;
synchronized(lock)
{
  lock.notifyAll();
}


2. Когда идет доступ к компонентам Swing из другого потока, надо использовать такой метод:
Код
SwingUtilities.invokeLater(new Runnable()
{
  public void run()
  {
    pMain.setTitle("Бла-бла-бла");
  }
});


3.
Цитата(x3bytes @  10.11.2006,  22:24 Найти цитируемый пост)
то при повторном нажатии на JPanel выскочит ошибка at java.lang.Thread.start(Thread.java:571)

Это не ошибка, это ее кусок, по которому невозможно, что-то понять.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
x3bytes
Дата 11.11.2006, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Beaver



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

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



Спасибо огромное тебе LSD !!!  smile 
Столько перерыл справок и не смог по ним сделать работующую прогу.
А по твоим словам сразу получилось.

Привожу пример изменёной программы. Теперь я так понимаю всё сделано как надо и процесс пока он не нужен не обрабатывается процессором. 

Код

package testapp;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;


public class PicPanel extends JPanel{
    
    
    private boolean fullStop = false;
    private boolean work = false;
    
    int i=0;
    Image image;
    
    JFrame pMain;
    public Thread thread = null; 
    
    public PicPanel(String source, JFrame pM){
        String file = source;
        pMain = pM;
        try{
            image = super.getToolkit().getImage(this.getClass().getResource(file));
        } catch(Exception e){
            JOptionPane.showMessageDialog(this, e.getMessage());
            System.out.println(e.getMessage());
        }
        
        thread = new Thread(new Runnable(){
            public void run(){
                
                
                while(!fullStop) {    
                    while(work) {
                        i++;
                        pMain.setTitle("i = "+i);
                    }
                    try {
                        synchronized(thread) {
                            thread.wait();
                        }
                    } catch(InterruptedException e) {
                    }
                }
            }
            
        });
        
        thread.start();
        
        this.setCursor(new Cursor(Cursor.HAND_CURSOR));
        
        //Обработчики событий мыши
        this.addMouseListener(new MouseAdapter() {
            //Invoked when a mouse button has been pressed on a component.
            public void mousePressed(MouseEvent event) {
                
                work = true;
                synchronized(thread) {
                    thread.notifyAll();
                }

            }
            
            //Invoked when a mouse button has been released on a component.
            public void mouseReleased(MouseEvent event) {
                
                work = false;

            }
            
            //Invoked when the mouse button has been clicked (pressed
            //and released) on a component.
            public void mouseClicked(MouseEvent e){}
            
            //Invoked when the mouse enters a component.
            public void mouseEntered(MouseEvent e){}
            
            //Invoked when the mouse exits a component.
            public void mouseExited(MouseEvent e){}
            
        });
        this.addMouseMotionListener(new MouseMotionListener() {
            //Invoked when the mouse cursor has been moved onto a component
            //but no buttons have been pushed.
            public void mouseMoved(MouseEvent event){
            }
            
            //Invoked when a mouse button is pressed on a component and then
            //dragged.
            public void mouseDragged(MouseEvent e) {
            }
        }
        );
    }
    
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g = g.create();
        g.drawImage(image, 0, 0, this);
    }
    
    protected void Destroy(){
        fullStop = true;
        work = false;
        synchronized(lock) {
            lock.notifyAll();
        }
    }
    
}


правда не совсем понял практическое применение invokeLater()
PM MAIL   Вверх
powerOn
Дата 11.11.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


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

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



Цитата(x3bytes @  11.11.2006,  18:10 Найти цитируемый пост)
правда не совсем понял практическое применение invokeLater() 

Почитай тут.


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

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


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



invokeLater() нужен для того чтобы выполнять действия в потоке обработки сообщений AWT.
Если мы будем одновременно из разных потоков менять данные, то может нарушится их целостность. Выхода два: синхронизировать доступ к данным, или делать все из одного потока. Синхронизация плоха тем, что замедляет скорость работы (синхронизированный вызов функции ощутимо дольше, не синхронизированного), поэтому для Swing был выбран второй метод (такой же подход выбран и для SWT, и для WindowsForms), а invokeLater() это просто способ его реализации.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
x3bytes
Дата 13.11.2006, 04:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Beaver



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

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



А можно пример с оптимизацией на основе кода(приведеного выше) с использованием этой функции?
У меня всю дорогу только получается завесить приложение этой функцией.
PM MAIL   Вверх
LSD
Дата 13.11.2006, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



Я тебе уже дал пример как надо его использовать. Ты его пробовал?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
x3bytes
Дата 13.11.2006, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Beaver



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

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



Да спасибо!
Спасибо за помощь  smile 
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.0783 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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