Instanze in Thread laufen lassen ?

Code46

Erfahrenes Mitglied
Hi Leute,

Ich wollte gerne eine Instanz einer Klasse im Thread laufen lassen. Ist dies möglich ? Ich ein GUI der Test heißt und dann habe ich noch ein anderes Program das PhoneToSender im hintergrund laufen soll. Da ich Strings von dem PhoneToSender lesen werde muss es immer ausgelesen werden. Ist da Sinnvoll einen Thread einzubauen ?

Wenn ihr mir behilflich sein könntet, würde ich mich sehr freuen.


Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * @author SerSa
 */


public class Test extends JFrame implements ActionListener{

    public static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    
    public final JButton btnclose = new JButton("Close");
    public final JTextArea txtarea = new JTextArea(5,10);
   
    
  
 public Test() throws Exception {
        super("NFC Attendance System"); 
        
        
        
        String[] columnNames = {"Student ID",
                                "Student Name",
                                "Lecture Room",
                                "Date",
                                "Time"};
 
        Object[][] data = {   };
        final JTable table = new JTable(data, columnNames);
        JScrollPane tableContainer = new JScrollPane(table);
        
        
        
        
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 
        final JPanel north = new JPanel();
        final JPanel south = new JPanel();
        final JPanel east = new JPanel();
        final JPanel west = new JPanel();
        final JPanel center = new JPanel();
        
        add("North", north);
        add("South", south);
        add("East", east);
        add("West", west);
        add("Center", center);
        
       
        north.setBorder(BorderFactory.createTitledBorder("Date&Time Display"));
        final BoxLayout layout = new BoxLayout(north, BoxLayout.X_AXIS);
        final JLabel datetime = new JLabel("");
        datetime.setFont(new Font("Verdana", Font.PLAIN, 50));
        north.add(datetime);
        
        
        center.setBorder(BorderFactory.createTitledBorder("NFC Record"));
        center.setLayout(new BorderLayout());
        center.add(tableContainer, BorderLayout.CENTER);
        
       // table.setText(IsmbSnepConnection.received);
            
        
        south.setBorder(BorderFactory.createTitledBorder("Selection"));
        south.add(btnclose);
        final BoxLayout la = new BoxLayout(south, BoxLayout.X_AXIS);
        
        btnclose.addActionListener(this);
        setSize(700, 600);
        setVisible(true);
        
        new Timer().scheduleAtFixedRate(new TimerTask()
        {
            @Override
            public void run() {
                datetime.setText(dateFormat.format(new Date()));
            } 
        }, 0, 100);
    }
     
     
    public static void main(String[] args) throws Exception {
        final Test me = new Test();
        
        PhoneToSender f = new PhoneToSender(); // Dies im Thread laufen lassen ************
    }

    
    @Override
    public void actionPerformed(ActionEvent e) {

            if(e.getSource()== btnclose)
            {
                System.exit(0);
            }
       
        
       
    }
}

Danke
 

Der Wolf

Erfahrenes Mitglied
Hey,

sollte deine Instanz der "PhoneToSender" Klasse zum Beispiel von einem Socket lesen wollen, was ja ein blockierender Prozess ist, dann macht es auf jedenfall Sinn, dass in einem eigenen Thread laufen zu lassen.

Gruß,
Wolf
 

Code46

Erfahrenes Mitglied
Jap es liest etwas aus einem Socket. Kannst du mir vielleicht ein beispiel zeigen wie ich den Thread bei mir in Code einbauen könnte ?

Danke
 

Der Wolf

Erfahrenes Mitglied
Eine Möglichkeit wäre zum Beispiel deine Klasse "PhoneToSender" von "Thread" erben zu lassen und die run-Methode zu überschreiben.

Java:
public class PhoneToSender extends Thread {

    @Override
    public void run() {

        while (true) {

            // Lese von Socket. 

            // Mach irgendwas mit den empfangenden Daten

        }

    }

}

Nachdem du dann eine Instanz von PhoneToSender erzeugt hast musst du nur noch die start-Methode aufrufen und voila, die endlos lang laufende run-Methode wird in einem eigenen Thread ausgeführt.

Java:
PhoneToSender instance = new PhoneToSender();
instance.start();

Aber Achtung. Den Code hier, so kurz er auch sein mag, ist nicht von mir getestet, sonder aus dem Kopf gerade runter geschrieben. Kann also auch noch ein Fehler drin sein.

Die andere Möglichkeit wäre, dass deine Klasse "PhoneToSender" das Interface "Runnable" implementiert.

Am besten guckst du dir mal verschiedene Tutorials in der Richtung an. Da gibt es eigentlich eine Menge zur Client-Server Kommunikation und ähnliches. Gerade im Bereich Java ist einiges mit Netzwerk-Kommunikation verfügbar.

Gruß,
Wolf
 

Code46

Erfahrenes Mitglied
In meiner Klasse PhonToSender Habe ich eine Method die dies genau macht. Wie kann ich eine instanze davon erstellen ?
Code:
/*
 * PhoneToSender - Simple test of IsmbSNEPConnection: Communication flow from Phone to Reader
 * 
* Copyright (C) 2012  Antonio Lotito <lotito@ismb.it>
 * 
 * This file is part of ISMB-SNEP-JAVA LIBRARY.
 * 
 * ISMB-SNEP-JAVA LIBRARY is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.
 * 
 * ISMB-SNEP-JAVA LIBRARY is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  
 * See the GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with ISMB-SNEP-JAVA-LIBRARY. If not, see http://www.gnu.org/licenses/.
 */

package test;


import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;

@SuppressWarnings("restriction")
public class PhoneToSender  
{
	CardTerminal terminal = null;	     
	//IsmbSnepConnection n=null;
	IsmbSnepConnection n=null;
	String info="";
	String id_trans="";
	Timer timer;
	
	public static void main(String[] args) 
	{		 		 	
		new PhoneToSender();				
	}
	
	public PhoneToSender()	
	{		
		 TerminalFactory factory;
		 List<CardTerminal> terminals;			
		 //List all available terminals	 		 
		 try {
			System.out.println("Get factory");
			 factory = TerminalFactory.getDefault();
			 System.out.println("Get terminals");
			 terminals = factory.terminals().list();          
			 if (terminals.size() == 0) {
				 System.out.println("There are not terminals.");
				 terminals = null;			 
			 }
			 else {
				 terminal=terminals.get(0);
				 System.out.println("Terminal name: "+terminal.getName());
			 }	
			} 
			catch (CardException c) {
				System.out.print(c.getMessage());
				terminals = null;			
			}		 
		 timer=new Timer();
		 timer.schedule(new InitiatorTask(), 500);		 
	}
	
	public class InitiatorTask extends TimerTask 
	{			 						
	    public void run() 
	    {
	    	ThreadSender t=new ThreadSender();
	    	t.run();
	    }
	}
	
	//THREAD
	public class ThreadSender implements Runnable 
	{			
		public void run() 
		{
			try 
			 {                				
				 if(n!=null)
					 n.close();				 
				 n = new IsmbSnepConnection(terminal);			
				 
				 n.setDebugMode();				
                        try {
                            //n.receivingProcedured();
                            n.receivingProcedureEnhanced();
                        } catch (UnsupportedEncodingException ex) {
                            Logger.getLogger(PhoneToSender.class.getName()).log(Level.SEVERE, null, ex);
                        }
				 System.out.println("Finished");
			 } catch (InterruptedException ex) { 
                    Logger.getLogger(PhoneToSender.class.getName()).log(Level.SEVERE, null, ex);
                }
			 catch (IsmbSnepException e) 
			 {
				 if (n != null) 
				 {
	                 try{
	                    n.close();
	                    } catch (IsmbSnepException e1) {System.out.println(e1);}	             
				 }				 
				 System.out.println(e.getMessage());	 		 		 
			 }
			 finally
			 {
				 try {
					 n.close();
				     } catch (IsmbSnepException e) {e.printStackTrace();}				 			 
			 }		 			 		
		}
	}	
}
 

sheel

I love Asm
Gibt es einen Grund,warum das nicht nur eine Methode, sondern eine ganze Klasse ist?

Es reicht das run auch direkt in der Oberklasse.
 

Code46

Erfahrenes Mitglied
Ich habe eine instanze erstellt PhoneToSender PS = new PhoneToSender();
Jedoch kann ich nicht PS.start(); order PS.run(); aufrufen ?
 

Der Wolf

Erfahrenes Mitglied
Weil deine "PhoneToSender" Klasse nicht von "Thread" erbt besitzt sie auch keine "Start" Methode. Statt dessen erbt ja die innere Klasse von "Thread" und die andere innere Klasse implementiert "Runnable".

Vielleicht solltest du dich erst noch etwas mehr mit den Grundlagen von Klassen beschäftigen, bevor du die mit Multi-Threading beschäftigst?

Gruß,
Wolf