Einführung in die objektorientierte Programmierung: Threads

Befehle

Thread mit extends

class MyThread extends Thread

Erbt von Thread


public void run(){ .... }

Definiert Thread


Thread myThread = new MyThread();

Erzeugt Thread-Objekt


myThread.start();

Startet Thread

Thread mit Runnable

class Berechnung implements Runnable

Erbt vom Interface


public void run(){ .... }

Definiert Thread


Runnable target = new Berechnung()

Erzeugt Runnable-Objekt


Thread myThread = new Thread(target);

Erzeugt Thread-Objekt


myThread.start();

Startet Thread

sleep

sleep(zahl);

Thread schläft zahl Millisekunden

volatile

volatile boolean b=true;

Variable soll für alle Threads aktuell gehalten werden

Interrupt

t.interrupt();

Unterbricht Thread t


interrupted()

Überprüft den Interrupt des aktuellen Threads


t.IsInterrupted()

Überprüft den Interrupt von t


catch(InterruptedException ie)

Ist catch-Klausel für Interrupt

yield

yield

Signalisiert, dass der Thread den Prozessor freigeben will

Sychronisierung

synchronized void meth(){ ... }

Synchronisiert die Methode


synchronized static void meth(){ ... }

Synchronisiert die statische Methode


synchronized (Ausdruck) Block

Synchronisiert den Block, Ausdruck steht für ein Objekt

Wait

X.wait()

Warteliste für X


X.notify()

Wählt Thread aus Warteliste von X aus


X.notifyAll()

Wählt alle Threads aus Warteliste von X aus

 

Zwei parallele Threads

parallel.java 
public class parallel implements Runnable{
 String wort="";
 
 parallel(String w){
 wort=w ;
 }
 public void run(){
   for (int i=0;i<100;i++)
   System.out.println(wort);
   }
 public static void main(String[] args) {
   Runnable p1=new parallel("a");
   Thread t1=new Thread(p1);
   Runnable p2=new parallel("b");
   Thread t2=new Thread(p2);
   t1.start();
   t2.start();
   }
   }
 

Zwei parallele Threads mit Sleep und verschiedenen Schlafzeiten

warten.java 

public class warten extends Thread{
String wort="";
int zeit=0;

warten(String w,int t){
wort=w ; zeit=t;
}
 public void run(){
   while (true){
   System.out.println(wort);
   try{
   sleep(zeit);
   }
   catch(InterruptedException ie){}
   }
   }
 public static void main(String[] args) {
   Runnable p1=new warten("a",5000);
   Thread t1=new Thread(p1);
   Runnable p2=new warten("b",8000);
   Thread t2=new Thread(p2);
   t1.start();
   t2.start();
   }
   }

Synchronisierter Zugriff auf Konten

konten_monitor2.java 

public  class konten_monitor2 extends Thread{
static int konto[]=new int[100];
int zeit=0;
int betrag=0;

konten_monitor2(int b,int t){
betrag=b ; zeit=t;
}
 public void run(){
   buchen();
   }
   
   public void buchen(){
   synchronized(konto) {
   int k=konto[1];
   try{
   sleep(zeit);
   }
   catch(InterruptedException ie){}
   if (k>=betrag) konto[1]=konto[1]-betrag;
   System.out.println(k+" - "+betrag+" = "+konto[1]);
   }
   }
 public static void main(String[] args) {
   konto[1]=500;
   Runnable p1=new konten_monitor2(400,1000);
   Thread t1=new Thread(p1);
   Runnable p2=new konten_monitor2(200,5000);
   Thread t2=new Thread(p2);
   t1.start();
   t2.start();
   }
 }

Erzeuger-Verbraucher-Problem

Prozess.java 

import java.util.*;
public class Prozess extends Thread{
   int lager[]=new int[100];
   int zeit=0;
   int nr=-1;
   
   public synchronized void holen() throws InterruptedException{
   try{
   if (istLeer()) wait();
   notify();
   int a=lager[nr];
   System.out.println("Verbraucht "+nr+" "+a);
   nr--;
   // notify();
   }
   catch(InterruptedException ie){}
   }
 public synchronized boolean istLeer(){
   return (nr==-1);
   }
   
   public synchronized void ablegen(int a) throws InterruptedException {
   try{
   if (istVoll()) wait();
   notifyAll();
   nr++;
   lager[nr]=a;
   System.out.println("Erzeugt "+nr+" "+lager[nr]);
   // notify();
   }
   catch(InterruptedException ie){}
   }
 public synchronized boolean istVoll(){
   return (nr==99);
   }
 public static void main(String[] args) {
   Prozess lager=new Prozess();
   Runnable p1=new erzeuger(lager,30);
   Thread t1=new Thread(p1);
   // Runnable p2=new Prozess(200,500);
   // Thread t2=new Thread(p2);
   Runnable v1=new verbraucher(lager,20);
   Thread t3=new Thread(v1);
   t1.start();
   // t2.start();
   t3.start();
   }
   }
 
erzeuger.java 

import java.util.*;
public class erzeuger extends Thread{
   int zeit=0;
   Prozess lager;
 erzeuger(Prozess lager,int t){
   zeit=t; this.lager=lager;
   }
 public void run(){
   while(true){
   try{
   int a=(int) (Math.random()*1000);
   lager.ablegen(a);
   if (lager.nr==99) zeit=30;
   if (lager.nr==0) zeit=10;
   sleep(zeit);
   }
   catch(InterruptedException ie){}
   }
   }
}
 
verbraucher.java 

import java.util.*;
public class verbraucher extends Thread{
   int zeit=0;
   Prozess lager;
   
   verbraucher(Prozess lager,int t){
   zeit=t; this.lager=lager;
   }
 
 public void run(){
   while(true){
   try{
   if (lager.nr==0) zeit=30;
   if (lager.nr==99) zeit=10;
   lager.holen();
   sleep(zeit);
   }
   catch(InterruptedException ie){}
   }
   }
}
 

Applet mit Unterbrechung

ThreadApplet.html 


<html>
<head>
<title>ThreadApplet-Applet</title>
</head>
<body>
<h1>ThreadApplet-Applet</h1>
<hr>
<applet code="ThreadApplet.class" width="300" height="300">
</applet>
<hr>
</body>
</html> ThreadApplet.java
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class ThreadApplet extends Applet{
   // Anfang Variablen
   private Button button1 = new Button();
   private TextField textField1 = new TextField();
   private Button button2 = new Button();
   private Button button3 = new Button();
   private Button button4 = new Button();
   Thread t1=null;
   Zaehlen p1=null;
   // Ende Variablen
 
 public void init() {
   Panel cp = new Panel(null);
   cp.setBounds(0, 0, 300, 300);
   add(cp);
   // Anfang Komponenten
 button1.setBounds(48, 24, 121, 33);
   button1.setLabel("Start");
   cp.add(button1);
   button1.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
   p1=new Zaehlen(textField1);
   t1=new Thread(p1);
   t1.start();
   button1.setVisible(false);
   button2.setVisible(false);
   button3.setVisible(true);
   }
   });
 textField1.setBounds(112, 104, 145, 24);
   textField1.setText("0");
   cp.add(textField1);
   button2.setBounds(48, 176, 121, 33);
   button2.setLabel("Weiter");
   cp.add(button2);
   button2.setVisible(false);
   button2.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
   t1=new Thread(p1);
   t1.start();
   button1.setVisible(false);
   button2.setVisible(false);
   button3.setVisible(true);
 }
   });
   
   button3.setBounds(48, 216, 121, 33);
   button3.setLabel("Unterbrechen");
   cp.add(button3);
   button3.setVisible(false);
   button3.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
   t1.interrupt();
   button1.setVisible(true);
   button3.setVisible(false);
   button2.setVisible(true);
   }
   });
 }
}
 
Zaehlen.java
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.util.*;
public class Zaehlen extends Thread{
 private TextField textField1 = null;
   int i=0;
   
   
   Zaehlen(TextField tf){
   this.textField1=tf;
   }
   
   public void run(){
   try{
   while (true){
   i++;
   textField1.setText(""+i);
   sleep(1);
   }
   }
   catch(InterruptedException ie){}
   }
   }