Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > About Swing Thtreads


Автор: Nodir 22.7.2006, 13:46
Zdrastvuyte, izvenayus chto pishu ne russkim shriftom, potomushto seychas u moyom comp`e netu ix. Est vopros. GUI Swing prilojenie, est dve button`a "Start" "Stop". Po najatie Start`a zapuskaetsa perviy potok i uvelichivaet odnu peremennuyu. A po najatie Stop`a perviy Thread doljen zavershitsya, i vtoroy potok doljen brat znachenie uvelichennova peremennova. Esli est vremya kompiliruyte eto i posmotrite.
Код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;

public class TempThread extends JFrame implements ActionListener{
    public TempThread(String title){
     super(title);
     setSize(250, 150);
     setResizable(false);
     contentPane = getContentPane();
     GridLayout gr = new GridLayout(1, 2, 5, 5);
     contentPane.setLayout(gr);
     bStart = new JButton("Start");
     bStop = new JButton("Stop");
     contentPane.add(bStart);
     contentPane.add(bStop);
     addWindowListener(new WindowAdapter(){
         public void windowClosing(WindowEvent e){
             System.exit(0);
         }
     });
     bStart.addActionListener(this);
     bStop.addActionListener(this);
    }
    JButton bStart, bStop;
    Container contentPane;
    
    public static void main(String[] args) {
     TempThread wndw = new TempThread("Testing Threads");
     wndw.show();
    }
    public void actionPerformed(ActionEvent ev){
     String command = ev.getActionCommand();
     if (command.equals("Start")){
         FlWriter flw = new FlWriter("Start");
         flw.start();
     }     
     if (command.equals("Stop")){
         FlWriter flw = new FlWriter("Stop");
         flw.start();
     }
    }
}
class FlWriter extends Thread {
    public FlWriter(String bName){
        command = bName;
    }
    public /*volatile*/ boolean doStop = false;
    public long value = 123l;
    String command = "";
    public void run(){
        if (command == "Start"){
            write();
        }
        if (command == "Stop"){
            stoping();
        }
    }
    
    public void write(){
        try{    
            while (!doStop){
                System.out.println("Going...");
                System.out.println("value do = "+value+"\n\n");
                sleep(600);
                value += 10;
                if (doStop) break;
            }
        
        } catch (Exception ex){
            System.err.println("Something from sleep...");
        }
    }
    public void stoping(){
        try{
            doStop = true;
            System.out.println("\n\n\n doStop = "+doStop);
            System.out.println("value do = "+value+"\n\n");
        } catch (Exception ex){
            System.err.println("Hey, err "+ex);
        }        
    }
    public void contining(){
        try{
        } catch (Exception ex){
            System.out.println("Hey, err "+ex);
        }        
    }
}

 

Автор: LSD 22.7.2006, 15:39
1. Строки сравниваются equals(), а не ==.

2. Если нажата кнопка Start, то ты запускаешь новый поток и выполняешь в нем write() (он и начинает писать в консоль).
А если нажата кнопка Stop, то ты запускаешь новый поток и выполняешь в нем stoping(), но это влияет только на этот поток. Он успешно завершает свою работу так ее и не начав.
К тому же ты никак не передаешь результат из первого потока во второй.

Тебе надо при нажатии Stop сказать для первого потока stoping() и дождаться когда он остановится (Thread.join()). Затем получить результат вычислений первого потока, создать второй, передав ему результат работы первого, и запустить второй поток. 

Автор: Nodir 23.7.2006, 06:22
Во время работы первого потока как я могу вызвать для него stopping(). И какую роль играет здесь 
Thread.join(), подробнее pls, я не профессионал. Если можно   smile  

Автор: powerOn 23.7.2006, 20:24
Цитата(Nodir @  23.7.2006,  07:22 Найти цитируемый пост)
Во время работы первого потока как я могу вызвать для него stopping()

Второй поток должен обладать ссылкой на объект первого потока, что бы иметь возможность посылать ему сообщения (т.е. вызывать его методы).

Цитата(Nodir @  23.7.2006,  07:22 Найти цитируемый пост)
И какую роль играет здесь Thread.join(), подробнее pls

Заместо Thread (насколько я понял) должна быть ссылка на первый объект-поток. Вызов метода join() для первого потока из контекста второго потока заставит пристановиться вызывающий поток (второй) до завершения работы первого. Второй поток как бы повисает на вызове метода join() Первый поток будет завершен, если его метод run() возвратит управление или он будет прерван по случаю выброса исключения. Как только первый поток завершит работу, вызов метода join() возвратит управление, тем самым выполнение второго потока возобновиться. 
Этот прием называется "объединение потоков" (join - англ. соединять, объединять, связывать, скреплять).

Цитата(Nodir @  23.7.2006,  07:22 Найти цитируемый пост)
я не профессионал

удивительно, я тоже!  smile 
 

Автор: Nodir 23.7.2006, 22:56
Если правильно понял то должен получится вот так, но не тот... Где ошибка?...
Вот изменение.
Код

class FlWriter extends Thread {
    /*-------------------*/Thread thrd;/*-------------------*/
    public FlWriter(String bName){
        command = bName;
    }...
          if (command.equals("Start")){
        /*-------------------*/thrd = Thread.currentThread();/*-------------------*/
        write();
    }...
    public void stoping(){
        try{
            doStop = true;
            /*-------------------*/thrd.join();/*--------------------*/
            System.out.println("\n\n\n doStop = "+doStop);
...
 

Автор: powerOn 23.7.2006, 23:26
Посмотри вот этот код:
Код

import javax.swing.JOptionPane;

public class NewJFrame extends javax.swing.JFrame {
    MyThread1 thread1 = null;
    MyThread2 thread2 = null;
    /** Creates new form NewJFrame */
    public NewJFrame() {
        initComponents();
    }
    
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">
    private void initComponents() {
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        getContentPane().setLayout(new java.awt.GridLayout(0, 1));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jButton1.setText("\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        getContentPane().add(jButton1);

        jButton2.setText("\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439");
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton2MouseClicked(evt);
            }
        });

        getContentPane().add(jButton2);

        pack();
    }// </editor-fold>
    
    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {
        thread2 = new MyThread2();
        thread2.setThread1(thread1);
        thread2.start();
        
    }
    
    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
        thread1 = new MyThread1();
        thread1.start();
    }
    
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    // End of variables declaration
    
}

class MyThread1 extends Thread {
    private long counter = 0;
    private boolean stopFlag = true;
    public void run() {
        counter = 0;
        for(;stopFlag;) {
            System.out.println("counter = " + (++counter));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public long getCounter() {
        return counter;
    }
    
    public void stopThread() {
        stopFlag = false;
    }
    
    
}

class MyThread2 extends Thread {
    private long counter = 0;
    private MyThread1 thread1 = null;
    public void run() {
        if (thread1 != null && thread1.isAlive()) {
            thread1.stopThread();
            try {
                thread1.join();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        JOptionPane.showMessageDialog(null, "counter = " + thread1.getCounter());
    }
    
    
    public void setThread1(MyThread1 thread1) {
        this.thread1 = thread1;
    }
}


Имеется фрейм, на нем 2 кнопки. Нажатие первой кнопки создаст поток 1 (его класс MyThread1). Первый поток просто увеличивает свой внутренний счетчик и все. Нажатие на кнопку 2 приведет к созданию второго потока, который желает получить значение счетчика первого потока. Для того что бы это сделать он останавливает первый поток и ждет его завершения, послечего получает значения счетчика.
Вот код остановки и ожидания завершения первого потока (он в методе run() класса MyThread2):
Код

if (thread1 != null && thread1.isAlive()) {
            thread1.stopThread();
            try {
                thread1.join();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
 

Автор: Nodir 24.7.2006, 19:14
Большое спасибо!  smile  smile  smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)