Thread interrupt, wie?

BaseBallBatBoy

Erfahrenes Mitglied
Hi!

Ich bin an einem Übungsbeispiel mit Threads.
Nun, Threads kann man in Java auf zwei Arten machen:
1. extends Thread
2. implements Runnable

Die Variante mit der Thread Klasse hat bei mir auch super funktioniert,
aber wenn ich es mit Runnable lösen will gibts Probleme.
Nämlich da, wenn ich ein Interrupt werfen möchte um das ganze zu stoppen.

Hier mal der Code mit der Thread Klasse (3 Files):
BillyBall.java
Code:
public class BillyBall extends Thread {
	private Ball ball;
	
	public BillyBall (Ball ball){
		this.ball = ball;
	}
	
	public void run() {
		while(true) {
			ball.repaint();
			
			if(isInterrupted()) {
				return;
			}
			
			try {
				Thread.sleep(50);
			} catch(InterruptedException ie){
				return;
			}
		}
	}
}

Billard.java
Code:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;

public class Billiard extends JFrame implements ActionListener {
	BillyBall bball;
	Ball ball;
	Button stop;
	
	public Billiard(){
		this.setLayout(new BorderLayout());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Bouncing Ball");
		Dimension d = new Dimension(800, 400);
		this.setMinimumSize(d);
		this.setSize(800,400);
		stop = new Button("Stop");
		add(stop,BorderLayout.SOUTH);
		stop.addActionListener(this);
		ball = new Ball(this);
		bball = new BillyBall(ball);
		add(ball,BorderLayout.CENTER);
		add(stop,BorderLayout.NORTH);
		
		bball.start();
		
		this.setVisible(true);
	}

	public void actionPerformed(ActionEvent arg0) {
		if(arg0.getSource() == stop) {
			bball.interrupt();
		}
	}
	
	public static void main(String args[]) {
		new Billiard();
	}
}

Ball.java
Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Ball extends JComponent {
	private JFrame frame;
	private Dimension pos;
	private int velocityY;
	private int velocityX;
	private int v;
	private final int durchmesser = 50;
	
	public Ball(JFrame frame){
		this.frame = frame;
		v=5;
		velocityY=v;
		velocityX=v;
		pos = new Dimension(100,100);
	}
	
	protected void paintComponent(Graphics arg0) {
		Insets i = this.getInsets();
		int paintAreaWidth = this.getWidth() - i.right-i.left;  //zeichenfläche berechnen  
        int paintAreaHeight = this.getHeight() - i.bottom-i.top;
        int rightBound = this.getWidth()-i.right;
        int leftBound = i.left;
        int topBound = i.top;
        int bottomBound = this.getHeight()-i.bottom;
		pos.width+=velocityX;
		pos.height+=velocityY;
		
		if(bottomBound <= (pos.height+durchmesser)) {
			velocityY =-1*v;
		}
		
		if((pos.height)< topBound) {
			velocityY =1*v;
		}
		
		if( (rightBound) < (pos.width+durchmesser)) {
			velocityX =-1*v;
		}
		
		if(pos.width <= leftBound) {
			velocityX =1*v;
			System.out.println("linker rand");
		}
		
		arg0.setColor(Color.BLACK);
		arg0.drawOval(pos.width, pos.height, durchmesser, durchmesser);
	}
}


Wenn ich nun das ganze mit Runnable machen will, ändere ich in BillyBall.java mal folgendes (anstatt extends Thread):
Code:
public class BillyBall implements Runnable {


Und in Billard.java schreibe ich an stelle von bball.start();
Code:
new Thread(bball).start();


Das Problem ist aber der Aufruf in Billard.java
Code:
bball.interrupt();


Der funktioniert so nicht mit Runnable. Könnt ihr mir nun sagen, wie ich mit Runnable ein Interrupt werfen, bez. erkennen kann?

PS: Und wenn ihr grad noch so einen Verbesserungsvorschlag zu meinem allgemeinen Programmaufbau habt, nur raus damit! Wie gesagt, ich hab eben gerade mit Threads angefangen und nehme jeden Tipp dankend an!

Gruss BBBB
 
Hi Baseball...,

ich würde vorher mit der Methode
Code:
isAlive()
prüfen, ob der Thread noch aktiv oder schon tot ist.

Code:
if( myThread.isAlive() ){ 
                       myThread.interrupt(); 
             }

Bei Runnable mache ich das meistens so, dass ich eine Instanz erzeuge:

Code:
Thread myThread = new Thread(bball);
myThread.start();//ruft run() auf...

Dann kannst Du dem Thread direkt die Befehle erteilen, die an die 'bball' Instanz gehen sollen, sprich:
Code:
myThread.interrupt();...

Grüße Tim
 

Neue Beiträge

Zurück