Threads Cannot make a static reference..

Hallo Forum,
ich bin ein learn-by-doing Mensch und habe mir als Lernprogramm eine Art CPU-Benchmarktool überlegt. Folgendes Konzept:

Anzahl der Kerne auslesen, pro kern ein Thread erstellen.
Es wird mit einer Pi-methode dann gerechnet, also genauigkeitswert habe ich Konstant 987.654!
Pro Thread kommt dann noch ein Modifikator vor diese Zahl, abhängig von Kernen. Wird so gerechnet: Modifikator = 24/Anzahl Kerne.
Damit wird theoretisch gleich viel gerechnet, egal bei wie vielen Threads. Doch bevor ich mehrere Thread einrichten kann (verstand ich auch noch nicht ganz), muss es überhaupt mal laufen. (Ohne Threads klappt es natürlich gewollt, nur reizt es eben CPU nicht aus)
Fehlermeldung beim Erstellen eines Threads:

"Cannot make a static reference to the non-static method start() from the type Thread"
Derslebe Fehler kommt, wenn ich eine Funktion aufrufen will, die ein paar Variablen festlegen soll.
Also, folgender Code:

pithread.java
Java:
import java.util.Scanner;

public class pithread {
	public static void main(String[] args)
	{
		//CPU Kerne auslesen
		int cores = Runtime.getRuntime().availableProcessors();
		//Modifikator wird erstellt
		int modi = 24/cores;
		
		//Eingabe einleiten
		Scanner loopobj = new Scanner(System.in);
		System.out.println("Wieviele Loops sollen bearbeitet werden?: ");
		int loops = loopobj.nextInt();
		
		
		//for(int laufend = 0;laufend <= cores; laufend++) {
			
			threadsForPi threadObj = new threadsForPi();
			threadsForPi.setModi(modi, loops);
			
			try {
				threadsForPi.start();
				}
			catch (InterruptedException e) {
		            System.out.println("Thread interrupted");
		        }
		//}	
	}	
}

Und die threadsForPi.java:
Java:
public class threadsForPi extends Thread {
	int genauigkeit = 987654; //Anzahl Brueche fuer PI Berechnung
	int modi; //Modifikator, abhaengig von CPU Kernen
	int loops; //Anzahl der Durchgaenge
	
	@Override
	public void run(){
		
			//Zeitmessung Start
			long start = System.currentTimeMillis();
			
			//loops durchgehen
			for(int counter=1;counter <= loops; counter++) {
				//Pi berechnen
				gebePi(modi*genauigkeit);
			}
			
			//Ausgabe wenn fertig
			long duration = System.currentTimeMillis() - start;
			System.out.println("Kern " + 24/modi + "ist fertig. Dauer: " + duration + " ms");
		
	}
	
	public void setModi(int modi, int loops) {
		this.loops = loops;
		this.modi = modi;
		
	}
	
	public static void gebePi(int i) {
	       //Hier wird Pi mit den paramtern berechnet..
}

Danke für Hilfe!

edit: Fehlermeldung treten in der ersten Datei in Zeile 20 und 23 auf. Der Rest ist problemlos.
 
setModi ist eine Methode, die man auf Instanzen von threadsForPi aufrufen muss. Mit den Konstrukten hier:
Java:
threadsForPi.setModi(modi, loops);
...
threadsForPi.start();
versuchst Du auf dem Klassenobjekt direkt den Aufruf zu machen. Das geht nur mit statischen Methoden. Die Instanz, auf der Du die Aufrufe machen kannst, erzeugst du hier:
Java:
threadsForPi threadObj = new threadsForPi();
D.h. du musst die Methoden auf threadObj aufrufen. Du kannst das direkt aus X5-599's Post kopieren.

P.S. Methoden- und Variablendefinitionen sind schon schön nach Konvention benannt. Gefällt mir. Nun änder noch Deine Klassennamen so, dass sie mit einem Großbuchstaben anfangen. Dann sieht man im Code auch gleich viel schneller, wo man Klassenmethoden aufruft und wo man was mit einer Variablen macht.
 
Zuletzt bearbeitet von einem Moderator:
😳 facepalm

Wie auch immer, vielen Dank.

Jetzt muss ich allerdings 4 Threads erstellen, und wie das über ein Array geht, verstehe ich noch nicht. Bisher habe ich das so, doch er kann angebliche threadsForPi nicht in threadsForPi[] konvertieren:

Java:
threadsForPi threatObj[] = new threadsForPi();
		
		for(int laufend = 0;laufend <= cores; laufend++) {
			
			/*threadsForPi threadObj = new threadsForPi();
			threadObj.setModi(modi, loops);
			threadObj.start();*/
			
			threadObj[laufend] = new threadsForPi();
			
			
		}

Könnte mir jemand nochmal auf die Sprünge helfen? Das wäre Super!
 
1. es ist besser, die eckigen Klammern hinter den Typ zu schreiben. So sieht man bei der Typdefinition gleich, dass es sich um einen Array handelt.
2. Wenn du eine Array-Variable definierst, dann musst du ihr auch einen Array zuweisen:
Java:
threadsForPi[] threatObj = new threadsForPi[4];
Wie du siehst, musst du bei Initialisierung des Arrays bereits wissen, wieviele Elemente reinpassen sollen. Da du das weißt (4) ist Array hier geeignet. Wenn das nicht bekannt ist, musst du auf Listen ausweichen.
 
Vielen Dank - das ist einleuchtend. Wie groß es sein muss anzugeben, habe ich total vergessen (noch PHP gewöhnt) - und da ich ja ein Thread pro Kern haben möchte, weiß ich vorherrein, wieviele Threads ich brauche.

Noch eine anschließende Frage: Wieso wird mir gesagt, threadObj kann nicht als Variable aufgelöst werden? (Klar, ist ein Array, aber ich habe doch dahinter eckige Klammern?):

Java:
threadsForPi[] threatObj = new threadsForPi[cores];

		
		for(int laufend = 0;laufend < cores; laufend++) {
			
			/*threadsForPi threadObj = new threadsForPi();
			threadObj.setModi(modi, loops);
			threadObj.start();*/
			
			threadObj[laufend].setModi(modi, loops);
			threadObj[laufend].start();
			
		}

Das ist mir schleierhaft. Danke für deine Geduld.
 
Zuletzt bearbeitet:
[EDIT]Quatsch! Es ist ein reiner Schreibfehler (variablenname erst mit t am ende definiert, aber aufruf hat d am ende). Nu fang aber nicht an, uns hier als debugger zu missbrauchen 😉[/EDIT]

In dem kleinen Codeschnipsel ist alles richtig. Ich könnte mir vorstellen, dass du noch mehr Code dazwischen hast und die Variable threadObj in einem anderen Block definierst als der, wo Du sie später verwendest. Genauen Aufschluss würde das Posten des vollständigen Codes inkl. der kopierten Fehlermeldung des Compilers bringen. So ist da leider zu viel Kontext weggefiltert, der für die Fehlersuche wichtig ist.
 
Zuletzt bearbeitet von einem Moderator:
Nochmal editiert:
Also, hab noch tray catch eingebaut, und nunja, jetzt ensteht eben immer der Fehler. Mit einem Thread gehts, mit mehreren kommt eben der Output, dass ein Fehler aufgetreten sei. Im Code selbst sind natürlich keine Fehler mehr. habe auch die java Datei aktualisiert.
Wie debuggt man ab jetzt denn?

und hier meine pithread.java:

Java:
import java.util.Scanner;

public class pithread {
	public static void main(String[] args) throws InterruptedException
	{
		//CPU Kerne auslesen
		int cores = Runtime.getRuntime().availableProcessors();
		//Modifikator wird erstellt
		int modi = 24/cores;
		
		//Eingabe einleiten
		Scanner loopobj = new Scanner(System.in);
		System.out.println("Wieviele Loops sollen bearbeitet werden?: ");
		int loops = loopobj.nextInt();
		
		threadsForPi[] threatObj = new threadsForPi[cores];

		
		for(int laufend = 0;laufend < cores; laufend++) {
			
			/*threadsForPi threadObj = new threadsForPi();
			threadObj.setModi(modi, loops);
			threadObj.start();*/
			try {
				threatObj[laufend].setModi(modi, loops, laufend);
				threatObj[laufend].start();
			} catch (Exception e) {
				 System.out.println("Da ist wohl ein Fehler aufgetreten");
			}
		}
	}	
}

Meine threadsForPi.java:

Java:
public class threadsForPi extends Thread {
	int genauigkeit = 987654; //Anzahl Brueche fuer PI Berechnung
	int modi; //Modifikator, abhaengig von CPU Kernen
	int loops; //Anzahl der Durchgaenge
	
	@Override
	public void run(){
		
			//Zeitmessung Start
			long start = System.currentTimeMillis();
			
			//loops durchgehen
			for(int counter=1;counter <= loops; counter++) {
				//Pi berechnen
				gebePi(modi*genauigkeit);
			}
			
			//Ausgabe wenn fertig
			long duration = System.currentTimeMillis() - start;
			System.out.println("Kern " + 24/modi + " ist fertig. Dauer: " + duration + " ms");
		
	}
	
	public void setModi(int modi, int loops) {
		this.loops = loops;
		this.modi = modi;
		
	}
	
	public static void gebePi(int i) {
	      //PI berechnen 
	       }
}

Mehr ist nicht da..

edit: Kommando zurück, thread statt threat getippt 😱 Eben fix testen.

Schau nochmal oben, hab was am Posting geändert!
 
Zuletzt bearbeitet:
Nochmal editiert:
Also, hab noch tray catch eingebaut, und nunja, jetzt ensteht eben immer der Fehler. Mit einem Thread gehts, mit mehreren kommt eben der Output, dass ein Fehler aufgetreten sei. Im Code selbst sind natürlich keine Fehler mehr. habe auch die java Datei aktualisiert.
Wie debuggt man ab jetzt denn?

und hier meine pithread.java:

Java:
import java.util.Scanner;

public class pithread {
	public static void main(String[] args) throws InterruptedException
	{
		//CPU Kerne auslesen
		int cores = Runtime.getRuntime().availableProcessors();
		//Modifikator wird erstellt
		int modi = 24/cores;
		
		//Eingabe einleiten
		Scanner loopobj = new Scanner(System.in);
		System.out.println("Wieviele Loops sollen bearbeitet werden?: ");
		int loops = loopobj.nextInt();
		
		threadsForPi[] threatObj = new threadsForPi[cores];

		
		for(int laufend = 0;laufend < cores; laufend++) {
			
			/*threadsForPi threadObj = new threadsForPi();
			threadObj.setModi(modi, loops);
			threadObj.start();*/
			try {
				threatObj[laufend].setModi(modi, loops, laufend);
				threatObj[laufend].start();
			} catch (Exception e) {
				 System.out.println("Da ist wohl ein Fehler aufgetreten");
			}
		}
	}	
}

Meine threadsForPi.java:

Java:
public class threadsForPi extends Thread {
	int genauigkeit = 987654; //Anzahl Brueche fuer PI Berechnung
	int modi; //Modifikator, abhaengig von CPU Kernen
	int loops; //Anzahl der Durchgaenge
	
	@Override
	public void run(){
		
			//Zeitmessung Start
			long start = System.currentTimeMillis();
			
			//loops durchgehen
			for(int counter=1;counter <= loops; counter++) {
				//Pi berechnen
				gebePi(modi*genauigkeit);
			}
			
			//Ausgabe wenn fertig
			long duration = System.currentTimeMillis() - start;
			System.out.println("Kern " + 24/modi + " ist fertig. Dauer: " + duration + " ms");
		
	}
	
	public void setModi(int modi, int loops) {
		this.loops = loops;
		this.modi = modi;
		
	}
	
	public static void gebePi(int i) {
	      //PI berechnen 
	       }
}

Mehr ist nicht da..

edit: Kommando zurück, thread statt threat getippt 😱 Eben fix testen.

Schau nochmal oben, hab was am Posting geändert!

Ja, dashabe ich auch gemerkt, kurz nach dem Post 😀 Was ich mit den Exceptions anfangen soll, keine Ahnung. Nichtmal Google möchte mir helfen, bei Galileo Computing fand ich auch nichts. Gibt es dazu keine Dokumentation?:rtfm:
 
wernersbacher hat gesagt.:
Ja, dashabe ich auch gemerkt, kurz nach dem Post Was ich mit den Exceptions anfangen soll, keine Ahnung. Nichtmal Google möchte mir helfen, bei Galileo Computing fand ich auch nichts. Gibt es dazu keine Dokumentation?
Wenn ich von Dir lese, dass du im Internet nichst brauchbares zum Thema Exceptions gefunden hast, dann lässt das für mich nur den Schluss zu: "zu faul zu suchen/zu lesen" Das dann "Ich bin Leraning-By-Doing Mensch" zu nennen, ist eine Beschönigung. Mag sein, dass Das für Dich dann gut aussieht, aber Du wirst damit scheitern. Mach also vielleicht doch mal einen Schritt zurück und hangel Dich durch Tutorials zum Erlernen der Grundlagen, z.B. dem hier: The Java™ Tutorials Der Teil, der sich speziell mit Exceptions beschäftigt, ist hier zu finden: Lesson: Exceptions (The Java™ Tutorials > Essential Classes)
 
Wenn du noch kein Plan hast, dann lass das e.printStackTree bei Exception bitte nicht weg, generell mach es garnicht immerhin ist das einer der Java "Features" wo du ganz einfach sehen kannst was und wie und wo falsch gelaufen ist beim ausführen, mit der Fehlermeldung kannst du 98% den Code direkt nach Lesen des Fehlers fixen, sollte man sich also immer ausgeben lassen.
 
So bin auch wieder da 🙂

Ich stimme da meinen Vorrednern zu. Exception Handling solltest du dir auf jeden Fall mal ansehen.

Zu deinem Problem: Also ich vermute eine NullPointerException, da du zwar das Array erstellst aber dieses nicht mit Objekten füllst.

Java:
threadsForPi[] threatObj = new threadsForPi[cores]; //Leeres Array. Jedes Feld darin ist noch "null"
 
        
        for(int laufend = 0;laufend < cores; laufend++) {
            
            try {
                threadObj[laufend] = new threadsForPi(); //Hier wird das Objekt erzeugt und ins Array gelegt. Keine NullPointerException mehr.
                threatObj[laufend].setModi(modi, loops, laufend);
                threatObj[laufend].start();
            } catch (Exception e) {
                 System.out.println("Da ist wohl ein Fehler aufgetreten");
                 e.printStackTrace(); // Das hätte dir die NullPointerException (tatsächlich den ganzen Stacktrace) in der Konsole ausgegeben
            }
        }
 
Zuletzt bearbeitet:
Sorry, das ist nicht "learning by doing" sondern "too lazy for reading" und "asking for nothing". Es ist ein großer Fehler mit Kenntnissen aus einer Sprache wie PHP zu kommen und sein Verhalten bzgl. programmieren einfach zu adaptieren.

Kümmer dich erst mal um Objektorientierung und wichtige Konstrukte in Java, Fehlerbehandlung und Logging usw. Danach kannst du dich an Threading wagen. So macht das keinen Sinn.

Stelle Fragen dieser Art im Anfängerforum. Du hast zwar ein vermeintliches Fortgeschrittenenthema gewählt, diese "Probleme" gehören hier aber nicht hin.
 

Neue Themen


Zurück
Oben