Turtlegrafik mit Java

HomeAufgabenDruckenJava-Online

Threads


Die Betriebssysteme sind so leistungsfähig, dass man mehrere Programme parallel laufen lassen kann (Multitasking). Da meist nur ein Prozessor zur Verfügung steht, wird dies durch eine schnelle Umschaltung zwischen den Prozessen erreicht. Auch Teile eines Java-Programms können auf mehrere Prozesse aufgeteilt werden. Man spricht dabei von Threads.

Ohne Verwendung von Threads können zwei Turtle nicht gleichzeitig zeichnen sondern nur abwechlungsweise. Im folgenden Beispiel zeichnen zwei Turtle abwechslungsweise je eine Treppenstufe

 

// WithoutThread.java

import ch.aplu.turtle.*;
import java.awt.Color;

public class WithoutThread
{
  public WithoutThread()
  {
    Turtle john = new Turtle()
    Turtle laura = new Turtle(john)
    laura.setColor(Color.red);
    laura.setPenColor(Color.red);
    laura.setPos(0160);
    laura.left(90);
    for (int i = 0; i < 8; i++)
    {
      step(john);
      step(laura);
    }  
  } 
  
  private void step(Turtle t)
  {
    t.forward(20);
    t.left(90);
    t.forward(20);
    t.right(90);
  } 

  public static void main(String[] args)
  {
    new WithoutThread();
  }
}
   

 


Unter Verwendung von Threads können die beiden Turtle gleichzeitig zeichnen. Mit dem Aufruf der Methode draw() wird für jede Turtle ein eigener Thread erzeugt. Dieser enthält die Methode run(), in welcher das Zeichnen der Stufen erfolgt. Der Thread wird mit der Methode start() gestartet.

 

 

// ThreadEx1.java

import ch.aplu.turtle.*;
import java.awt.Color;

public class ThreadEx1 extends TurtleFrame
{
  public ThreadEx1()
  {
    Turtle john = new Turtle(this);
    Turtle laura = new Turtle(this);
    laura.setColor(Color.red);
    laura.setPenColor(Color.red);
    laura.setPos(0, 160);
    laura.left(90);
    draw(john);
    draw(laura);
  }

  private void draw(final Turtle t)
  {
    new Thread()
    {
      public void run()
      {
        for (int = 0; i < 8; i++)
          step(t);
      }
    }.start();
  }


  private void step(Turtle t)
  {
    t.forward(20);
    t.left(90);
    t.forward(20);
    t.right(90);
  }

  public static void main(String[] args)
  {
    new ThreadEx1();
  }
}
   

 

Erklärungen zum Programmcode:

new Thread()
{
    public void run()
    {
       ...
    }
}.start();

Es wird eine Instanz der Klasse Thread erzeugt, welche die Methode run() überschreibt. Beim Start des Threads wird diese Methode ausgeführt. Der Thread wird durch Aufruf der Methode start() gestartet

 private void draw(final Turtle t)

Da die Turtle t im Innern der neuen Klasseninstanz verwendet wird, muss t final (unveränderlich) deklariert sein

 

 


Im folgenden Beispiel zeichnen drei Turtles gleichzeitig Quadrate.

 

// ThreadEx2.java

import ch.aplu.turtle.*;
import java.awt.Color;

public class ThreadEx2 extends TurtleFrame
{
  public ThreadEx2()
  {
    Turtle john = new Turtle(this);
    Turtle laura = new Turtle(thisColor.red);
    Turtle sara = new Turtle(thisColor.green);
    john.setPos(-100-100);
    laura.setPos(-20-100);
    sara.setPos(60, -100);
    laura.setPenColor(Color.red);
    sara.setPenColor(Color.green);
    draw(john);
    draw(laura);
    draw(sara);
  }

  private void draw(final Turtle t)
  {
    new Thread()
    {
      public void run()
      {
        for (int = 0; i < 5; i++)
          square(t);
      }
    }.start();
  }

  private void square(Turtle t)
  {
    for (int i = 0; i < 4; i++)
      t.forward(40).right(90);
    t.forward(40);
  }

  public static void main(String[] args)
  {
    new ThreadEx2();
  }

}
 

 

In diesem Beispiel wird eine andere Möglichkeit gezeigt, Threads zu verwenden. Man deklariert eine innere Klasse TurtleThread, die von der Klasse Thread abgeleitet ist. In der Klasse TurtleThred wird die Methode run() überschrieben, die das Zeichnen der Figur ausführt. In der Applikationsklasse wird für jede Turtle eine Instanz der Klasse TurtleThread erzeugt und gestartet. Der Thread führt seine Methode run() aus.

 

// ThreadEx3.java

import ch.aplu.turtle.*;
import java.awt.Color;

public class ThreadEx3 extends TurtleFrame
{
  public ThreadEx3()
  {
    Turtle john = new Turtle(this);
    Turtle laura = new Turtle(thisColor.red);
    Turtle sara = new Turtle(thisColor.green);
    john.setPos(-135-50);
    laura.setPos(-10-50);
    sara.setPos(115, -50);
    laura.setPenColor(Color.red);
    sara.setPenColor(Color.green);
    new TurtleThread(john).start();
    new TurtleThread(laura).start();
    new TurtleThread(sara).start();
  }

  private class TurtleThread extends Thread
  {
    private Turtle turtle;

    private TurtleThread(Turtle turtle)
    {
      this.turtle = turtle;
    }

    public void run()
    {
      for (int = 0; i < 9; i++)
        segment(turtle);
    }
  }

  private void segment(Turtle t)
  {
    t.forward(140);
    t.right(160);
  }

  public static void main(String[] args)
  {
    new ThreadEx3();
  }
}
 

Erklärungen zum Programmcode:

private class TurtleThread extends Thread
{
    private Turtle turtle;

    private TurtleThread(Turtle turtle)
    {
      this.turtle = turtle;
    }
}

Der Konstruktor der Klasse TurtleThread kopiert eine Turtle-Referenz in eine Instanzvariable, die in run() verwendet wird
new TurtleThread(john).start() Erzeugt eine neue Instanz der Klasse TurtleThread für die Turtle john und startet den Thread

 

 

Im folgenden Beispiel wird an der Stelle des Mausklicks eine neue Turtle erzeugt und diese zeichnet einen Stern. Da jede Turtle im eigenen Thread zeichnet, können gleichzeitig beliebig viele zeichnende Turtles erzeugt werden.

 

// ThreadEx4.java

import ch.aplu.turtle.*;
import java.awt.event.*;

public class ThreadEx4
{
  public ThreadEx4()
  {
    final Turtle joe = new Turtle();
    joe.hideTurtle();
    joe.addStatusBar(30);
    joe.setStatusText("Click to create a new turtle");
    joe.addMouseListener(new MouseAdapter()
    {
      public void mousePressed(MouseEvent e)
      {
        Turtle = new Turtle(joe);
        t.setScreenPos(e.getPoint());
        star(t);
      }
    });
  }

  private void star(final Turtle t)
  {
    new Thread()
    {
      public void run()
      {
        for (int = 0; i < 5; i++)
          t.fd(40).rt(144);
      }
    }.start();
  }

  public static void main(String[] args)
  {
    new ThreadEx4();
  }
}
 

Erklärungen zum Programmcode:

Turtle t = new Turtle(joe)


Die Turtle joe wird dazu verwendet, dass sich alle mit Mausklick erzeugten Turtles in ihrem Fenster befinden

t.setScreenPos(e.getPoint())

Bei jedem Mausklick wird die neue Turtle t an die Position des Mausklicks gesetzt
 new Thread()
{
     public void run()
     {
        for (int i = 0; i < 5; i++)
          t.fd(40).rt(144);
     }
}.start();

Das Zeichnen eines Sterns erfolgt in einem neuen Thread