Threads

Diskutiere Threads im Java Basics - Anfänger-Themen Bereich.
M

MossMan_AT

Hallo,
Ich habe ein Problem mit Threads, welches sich im unteren Code zeigt. Aufgabe ist es in zwei Panels eine Ampelanlage zu zeichnen, wobei die beiden Ampeln synchron laufen müssen. Dies soll mit den Buttons Start, Stopp und Ende realisiert werden. Soweit funktioniert es, aber nicht ganz so wie ich es möchte, denn ich möchte zwei Threads erstellen, die in der main-Methode ihre run-Methode haben bzw. finden sollen. Dies mache ich mit t = new Thread(this); wobei die Definition zuvor durchgeführt wurde. Dann versuche ich herauszufinden, ob sie erstellt wurden- mit if(t.isAlive()) etc. ... um sicherzustellen, dass sie existieren, aber das tun sie nicht. Hoffe, dass unten im Code alles klar ist. Wenn ich sie erstelle und im Konstruktor ein Panel angebe, dann existieren sie, andernfalls nicht.

Vielen Dank!

Mit freundlichen Grüßen!

Das ist das Panel:
Java:
import java.awt.Color;

import java.awt.Graphics;
import java.awt.Color;

import java.awt.Graphics;

import javax.swing.JPanel;

public class JAmpelPanel extends JPanel implements Runnable{
    enum Phase {ROT, ROTGELB, GRUEN, GELB, AUS};    //ENUM definiert eine Klasse genauer, der Konstanten übergeben werden- hier die Farben
    private Phase phase = Phase.AUS;    //Ein Objekt der Klasse Phase wird erstellt
    Color coben, cmitte, cunten;
    
    //Ampelphasen:
        private int rotPhase = 3000;
        private int rotgelbPhase = 500;
        private int gruenPhase = 3000;
        private int gelbPhase = 3000;
        
    //Variable:
        private boolean go;
        private boolean f;
    
    //Die paint-Methode:
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        setBackground(new Color(0, 80, 0));
        
        switch(phase)
        {
            case ROT:
                coben = Color.red;
                cmitte = Color.gray;
                cunten = Color.gray;
                break;
                
            case ROTGELB:
                coben = Color.red;
                cmitte = Color.orange;
                cunten = Color.gray;
                break;
                
            case GRUEN:
                coben = Color.gray;
                cmitte = Color.gray;
                cunten = Color.green;
                break;
                
            case GELB:
                coben = Color.gray;
                cmitte = Color.orange;
                cunten = Color.gray;
                break;
        
            case AUS:
                coben = Color.gray;
                cmitte = Color.gray;
                cunten = Color.gray;
                break;
        }
        int h = getHeight() / 3-12;
        int b = getWidth() - 6;
        
        g.setColor(coben);
        g.fillOval(3,  3,  b,  h);
        
        g.setColor(cmitte);
        g.fillOval(3,  getHeight() / 3 + 6, b, h);
        
        g.setColor(cunten);
        g.fillOval(3,  2 * getHeight() / 3 + 9,  b,  h);
        
        g.setColor(Color.black);
        g.drawOval(3,  3,  b,  h);
        g.drawOval(3,  getHeight() / 3+ 6, b, h);
        g.drawOval(3, 2 * getHeight() / 3 + 9, b, h);
    }
    
    public void setPhase(Phase p)
    {
        phase = p;
        repaint();
    }
    
    public void setAus()
    {
        setPhase(Phase.AUS);
        repaint();
    }
    
    public void setRot()
    {
        setPhase(Phase.ROT);
        repaint();
    }
    
    public void setRotgelb()
    {
        setPhase(Phase.ROTGELB);
        repaint();
    }
    
    public void setGelb()
    {
        setPhase(Phase.GELB);
        repaint();
    }
    
    public void setGruen()
    {
        setPhase(Phase.GRUEN);
        repaint();
    }

    
    @Override
    public synchronized void run() {
        
    while(go == true)
    {
            
        try
        {
            setRot();
            Thread.sleep(rotPhase);
        
            setRotgelb();
            Thread.sleep(rotgelbPhase);
        
            setGruen();
            Thread.sleep(gruenPhase);
        
            setGelb();
            Thread.sleep(gelbPhase);
        }
        
        catch(Exception e1)
        {
            e1.printStackTrace();
        }
        
    }   
    
    }
    
    
    public void setGo(boolean f)
    {
        go = f;
    }
}
Nun folgt die main-Methode:
Java:
import java.awt.BorderLayout;


import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class DuoAmpel extends JFrame implements Runnable{

    //ContentPane:
    private JPanel contentPane;
    
    //Threads:
    private Thread t;
    private Thread d;
    
    //Panels:
    private JAmpelPanel panelAmpelOne;
    private JAmpelPanel panelAmpelTwo;
    
    //Buttons:
    private JButton btnStop;
    private JButton btnStart;
    private JButton btnEnde;
    
    //Ampelphasen:
    private int rotPhase = 3000;
    private int rotgelbPhase = 500;
    private int gruenPhase = 3000;
    private int gelbPhase = 3000;
    

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    DuoAmpel frame = new DuoAmpel();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public DuoAmpel() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        //Title:
        setTitle("Zweiampelsteuerung");
        
        //Panels:
        panelAmpelOne = new JAmpelPanel();
        panelAmpelOne.setBounds(10, 11, 134, 239);
        contentPane.add(panelAmpelOne);
        
        panelAmpelTwo = new JAmpelPanel();
        panelAmpelTwo.setBounds(154, 11, 134, 239);
        contentPane.add(panelAmpelTwo);
        
        //Buttons:
        btnStart = new JButton("Start");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //Wird so in der derzeitigen Fassung verwendet:
                var f = true;
                panelAmpelOne.setGo(f);
                t = new Thread(panelAmpelOne);
                t.start();
                
                //Sollte eigentlich über den Aufruf der Methode funktionieren- tut es aber nicht:
                // Das ist die Methode- findet sich weiter unten: automatik();
                
                //Problem mit Konstruktor, wird nicht erstellt, es wird kein Thread erstellt, wenn ich d = new Thread(this); schreibe:
                panelAmpelTwo.setGo(f);
                d = new Thread(panelAmpelTwo);
                /*if(d.isAlive())
                {
                    System.out.println("d Wurde erstellt");
                }*/
                d.start();
            }
        });
        btnStart.setBounds(302, 11, 89, 23);
        contentPane.add(btnStart);
        
        btnStop = new JButton("Stopp");
        btnStop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //btnStart.setSelected(false);
                
                var n = false;
                panelAmpelOne.setGo(n);
                panelAmpelTwo.setGo(n);
                
            }
        });
        btnStop.setBounds(302, 45, 89, 23);
        contentPane.add(btnStop);
        
        btnEnde = new JButton("Ende");
        btnEnde.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        btnEnde.setBounds(302, 79, 89, 23);
        contentPane.add(btnEnde);
    }

    
    private void automatik()
    {
        System.out.println("Erfolgreicher Aufruf der Funktion!");
        
        //Problem mit Konstruktor, Thread wird nicht erstellt:
        t = new Thread(this);
        t.start();
        
        /*if(t.isAlive())
        {
            t.start();
        }
        else
        {
            System.out.println("t Wurde nicht erstellt");
        }*/
        
        //Problem mit Konstruktor, Thread wird nicht erstellt:
        d = new Thread(this);
        d.start();
        
        /*if(d.isAlive())
        {
        d.start();
        }
        else
        {
            System.out.println("d Wurde nicht erstellt");
        }*/
        
    
        
        
        
    
        
    }
    
    
    @Override
    public synchronized void run() {
        
        
    while(btnStart.isSelected())
    {
    
    
        try
        {
                /*btnStart.repaint();
                btnStop.repaint();
                btnEnde.repaint();*/
            
                panelAmpelTwo.setRot();
                Thread.sleep(rotPhase);
        
                panelAmpelTwo.setRotgelb();
                Thread.sleep(rotgelbPhase);
        
                panelAmpelTwo.setGruen();
                Thread.sleep(gruenPhase);
        
                panelAmpelTwo.setGelb();
                Thread.sleep(gelbPhase);
        }
    
        catch(Exception e)
        {
            e.printStackTrace();
        }   
    }
    }
    
    
}
 
Blender3D

Blender3D

Ich habe ein Problem mit Threads, welches sich im unteren Code zeigt.
Ich habe Deinen Code etwas verkürzt.

Java:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class JAmpelPanel extends JPanel implements Runnable {
    enum Phase {
        ROT, ROTGELB, GRUEN, GELB, AUS
    }; // ENUM definiert eine Klasse genauer, der Konstanten übergeben werden- hier die
        // Farben

    private Phase phase = Phase.AUS; // Ein Objekt der Klasse Phase wird erstellt
    Color coben, cmitte, cunten;

    // Variable:
    private boolean running = false;
    private Thread thread;

    // Die paint-Methode:
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(new Color(0, 80, 0));

        switch (phase) {
        case ROT:
            coben = Color.red;
            cmitte = Color.gray;
            cunten = Color.gray;
            break;
        case ROTGELB:
            coben = Color.red;
            cmitte = Color.orange;
            cunten = Color.gray;
            break;
        case GRUEN:
            coben = Color.gray;
            cmitte = Color.gray;
            cunten = Color.green;
            break;
        case GELB:
            coben = Color.gray;
            cmitte = Color.orange;
            cunten = Color.gray;
            break;
        case AUS:
            coben = Color.gray;
            cmitte = Color.gray;
            cunten = Color.gray;
            break;
        }
        int height = getHeight() / 3 - 12;
        int width = getWidth() - 6;

        drawLight(g, 3, height, width, coben);
        drawLight(g, getHeight() / 3 + 6, height, width, cmitte);

        g.setColor(cunten);
        g.fillOval(3, 2 * getHeight() / 3 + 9, width, height);

        g.setColor(Color.black);
        g.drawOval(3, 3, width, height);
        g.drawOval(3, getHeight() / 3 + 6, width, height);
        g.drawOval(3, 2 * getHeight() / 3 + 9, width, height);
    }

    private void drawLight(Graphics g, int y, int height, int width, Color color) {
        g.setColor(color);
        g.fillOval(3, y, width, height);
    }

    private void setPhase(Phase p) {
        phase = p;
        repaint();
    }

    public void setAus() {
        setPhase(Phase.AUS);
        repaint();
    }

    @Override
    public synchronized void run() {
        while (running == true) {
            try {
                nextPhase(Phase.ROT, 3000);
                nextPhase(Phase.ROTGELB, 500);
                nextPhase(Phase.GELB, 3000);
                nextPhase(Phase.GRUEN, 3000);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    private void nextPhase(Phase phase, long delay) throws InterruptedException {
        if (!running)
            return;
        setPhase(phase);
        Thread.sleep(delay);
    }

    public void start() {
        stop();
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void stop() {
        running = false;
        thread = null;
    }
}
Java:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

@SuppressWarnings("serial")
public class DuoAmpel extends JFrame {

    // ContentPane:
    private JPanel contentPane;

    // Panels:
    private JAmpelPanel panelAmpelOne;
    private JAmpelPanel panelAmpelTwo;

    // Buttons:
    private JButton btnStop;
    private JButton btnStart;
    private JButton btnEnde;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    DuoAmpel frame = new DuoAmpel();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public DuoAmpel() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        // Title:
        setTitle("Zweiampelsteuerung");

        // Panels:
        panelAmpelOne = new JAmpelPanel();
        panelAmpelOne.setBounds(10, 11, 134, 239);
        contentPane.add(panelAmpelOne);

        panelAmpelTwo = new JAmpelPanel();
        panelAmpelTwo.setBounds(154, 11, 134, 239);
        contentPane.add(panelAmpelTwo);

        // Buttons:
        btnStart = new JButton("Start");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                panelAmpelOne.start();
                panelAmpelTwo.start();
            }
        });
        btnStart.setBounds(302, 11, 89, 23);
        contentPane.add(btnStart);

        btnStop = new JButton("Stopp");
        btnStop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                panelAmpelOne.stop();
                panelAmpelTwo.stop();
            }
        });
        btnStop.setBounds(302, 45, 89, 23);
        contentPane.add(btnStop);

        btnEnde = new JButton("Ende");
        btnEnde.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        btnEnde.setBounds(302, 79, 89, 23);
        contentPane.add(btnEnde);
    }

}
 
M

MossMan_AT

Vielen Dank! Das ist wesentlich eleganter und einfacher!

Liebe Grüße und noch einen schönen Tag
 
mrBrown

mrBrown

Ich habe ein Problem mit Threads, welches sich im unteren Code zeigt. Aufgabe ist es in zwei Panels eine Ampelanlage zu zeichnen, wobei die beiden Ampeln synchron laufen müssen. Dies soll mit den Buttons Start, Stopp und Ende realisiert werden. Soweit funktioniert es, aber nicht ganz so wie ich es möchte, denn ich möchte zwei Threads erstellen, die in der main-Methode ihre run-Methode haben bzw. finden sollen.
Sollen die zwei Ampeln synchron laufen, also Ampel 1 schaltet um und gleichzeitig schaltet Ampel 2 auch um, oder sollen sie einfach nur gleichzeitig laufen, aber wenn ob die gleichzeitig schalten ist egal?
 
M

MossMan_AT

Sie laufen synchron, aber danke, es hat mittlerweile schon funktioniert!

Liebe Grüße
Simon
 
Blender3D

Blender3D

Sie laufen synchron, aber danke, es hat mittlerweile schon funktioniert!
Da die Threads hintereinander gestartet werden und die Sleeping Phasen identisch sind entsteht der Anschein, dass die Ampeln synchron laufen. Das machen sie aber nicht wirklich.
Um sie zu synchronisieren, könnten man eine Ampel Serverklasse implementieren, die Ampeln steuert.
 
B

BestGoalkeeper

Ich denke auch dass Synchronisierung hier quasi nicht erwünscht ist... Denn wenn die Ampeln wirklich gleichzeitig schalten würden, dann würde ja gar kein Problem auftreten.
 
B

BestGoalkeeper

eben, die zeitliche Abfolge bei Ampeln ist ja fest vorgegeben... oder anders, ich sehe keinen Grund, warum eine "Instanz" nicht alle Ampeln einer Kreuzung steuern sollte.
 
mrBrown

mrBrown

Entweder eine zentrale Stelle schaltet immer alle Ampeln gleichzeitig oder die Ampeln "warte" aufeinander, zB mit CyclicBarrier.
 
Thema: 

Threads

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben