Threads Threads nicht nebenläufig

Paaax

Mitglied
Hallo ihr,

ich habe folgendes Problem. Wenn ich meine Datenbank mit Threads befüllen möchte werden diese nacheinander bearbeitet und nicht parallel. Ich muss zu meiner Entschuldigung sagen, dass ich mich mit Threads zum ersten Mal befasse und noch relativ unsicher im Umgang mit diesen bin. Hier ist mal meine gesamte Anwendung, würde mich über Feedback zum Problem freuen:

[Java]import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;

public class Hauptprogramm {

/**
* Diese Methode fordert den Benutzer auf einen Integer-Wert einzugeben
* und liefert diesen mittels return zurueck.
*
* @return int n - Parameter n zum Befuellen der Datenbank.
*/
protected static int liefereParameter()
{
try
{
int n = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

while(n<1)
{
System.out.println("Parameter n?");
n = Integer.parseInt(br.readLine());
}

return n;
}
catch(IOException e)
{
System.err.println(e);
return 0;
}
} // ende Methode liefereParameter

/**
* In dieser Methode startet die Anwendung. Zunaechst wird die Verbindung zur Datenbank hergestellt.
* Danach wird die Benutzereingabe mittels liefereParameter()-Methode abgefragt. Die Tabelle wird
* initialisiert und n entsprechend befuellt. Zu letzt wird die Verbindung zur Datenbank beendet.
*
* @param args
*/
public static void main(String[] args) {

int n;
long zeitvor, zeitnach;
Initialisierung eins, zwei;

Connection conn = Verbindung.verbinde();
Connection conn2 = Verbindung.verbinde();


n = liefereParameter();

Initialisierung.erstelleTabellen(conn);
zeitvor = System.currentTimeMillis();
if(n%2 == 0){
System.out.println("Test ifff");
eins = new Initialisierung(n, conn);
zwei = new Initialisierung(n/2, conn2);
eins.befuelleBranches(n);
eins.start();
zwei.start();
}
else{
System.out.println("Test else");
eins = new Initialisierung(n/2, conn);
zwei = new Initialisierung((n/2)+1, conn2);
zwei.befuelleBranches(n);
if(n>1)
eins.start();
zwei.start();
}

while(eins.isAlive() || zwei.isAlive())
continue;

zeitnach = System.currentTimeMillis();
Verbindung.beende(conn);
Verbindung.beende(conn2);

System.out.println("Zeit benötigt: " + (zeitnach - zeitvor) + " msec");
System.out.println("Disconnected!");
} // ende Methode main
} // ende Klasse Hauptprogramm
[/code]

Java:
import java.sql.*;
import java.util.Random;

public class Initialisierung extends Thread{
	
	int n;
	Connection conn = Verbindung.verbinde();
	
	Initialisierung(int n, Connection conn){
		this.n = n;
		this.conn = conn;
	}
	
	protected void befuelleBranches(int n){
		try{
		int element = 1;
		int balance = 0;
		String name = "aaaaaaaaaaaaaaaaaaaa";
		String adresse72 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
		StringBuilder anfrageBranches = new StringBuilder("insert into branches (branchname, balance, address) values");
		for (; element <= n; element++)
		{
			anfrageBranches.append("(?,?,?)");
			if (element < n)
				anfrageBranches.append(", ");
			else 
				anfrageBranches.append(";"); 
		}
		
		element = 1;
		PreparedStatement branches = conn.prepareStatement(anfrageBranches.toString());
		for (int i = 1; i <= n; i++)
		{
			//branches.setInt(element, ++id); //element++???????
			branches.setString(element, name);
			branches.setInt(++element, balance);
			branches.setString(++element, adresse72);
			element++; // loeschen????????
		}
		branches.executeUpdate();
		branches.close();
		}catch(SQLException e)
		{
			System.err.println(e);
			System.exit(1);		}
	}
	
	/**
	 * Diese Methode befuellt die einzelnen Relationen gemaeß der Aufgabenstellung..
	 * 
	 * @param n - Benutzereingabe der Klasse Hauptprogramm
	 * @param conn - Connection-Objekt der Verbindung zur Datenbank
	 */
	public void run()
	{
		System.out.println("Test run");
		int id = 0; // fortlaufende ID - Primaerschluessel der Relationen
		int balance = 0;
		int element = 1; // ParameterIndex fuer das PrepardedStatement
		String name = "aaaaaaaaaaaaaaaaaaaa";
		String adresse68 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
		String adresse72 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
		Random zufall = new Random(); // 
		
		try
		{
				conn.setAutoCommit(false);	

			//Befüllen der Relation accounts
			element = 1;
			id = 0;
			for(int x = 1; x <= 400; x++)
			{
				StringBuilder anfrageAccounts = new StringBuilder("insert into accounts (name, balance, branchid, address) values");
				//build.delete(0, build.length());
				//build.append("insert into accounts values");
				element = 1;
				for (; element <= n*250; element++)
				{
					anfrageAccounts.append("(?, ?, ?, ?)");
					if (element < n*250)
						anfrageAccounts.append(", ");
					else 
						anfrageAccounts.append(";");	
				}
				element = 1;
				PreparedStatement account = conn.prepareStatement(anfrageAccounts.toString());
				for(int i = 1; i <= n*250; i++)
				{
					//account.setInt(element, ++id); //element++ (1)
					account.setString(element, name); //element++ (2)
					account.setInt(++element, balance); //element++ (3)
					account.setInt(++element, (zufall.nextInt(n) + 1)); //element++ (4)
					account.setString(++element, adresse68); //element++ (5, ++ sorgt dafür das der Anfang 6 ist)
					++element; // könnte dann gelöscht werden?!
				}
				account.executeUpdate();
				account.close();
			}
	
			//Befüllen der Relation tellers
			StringBuilder anfrageTellers = new StringBuilder("insert into tellers (tellername, balance, branchid, address) values ");
			//build.delete(0, build.length());
			//build.append("insert into tellers values");
			element = 1;
			for (; element <= n*10; element++)
			{
				anfrageTellers.append("(?, ?, ?, ?)");
				if (element < n*10) 
					anfrageTellers.append(", ");
				else 
					anfrageTellers.append(";");
			}
			
			element = 1;
			id = 0;
			PreparedStatement teller = conn.prepareStatement(anfrageTellers.toString());
			for (int i = 1; i <= n*10; i++)
			{
				//teller.setInt(element, ++id);
				teller.setString(element, name);
				teller.setInt(++element, balance);
				teller.setInt(++element, zufall.nextInt(n) + 1);
				teller.setString(++element, adresse68);
				element++;
			}
			teller.executeUpdate();
			teller.close();
			System.out.println("Threadende");
		}
		catch(SQLException e)
		{
			System.err.println(e);
			System.exit(1);
		}
	} // ende Methode fuelleTabellen
	
	/**
	 * Diese Methode löscht zunächst eventuell vorhandene Relationen aus der Datenbank
	 * um diese dann im Initialzustand neu anzulegen. 
	 * 
	 * @param conn - Connection-Objekt der Verbindung zur Datenbank
	 */
	protected static void erstelleTabellen(Connection conn)
	{
		try
		{
			Statement stmt = conn.createStatement();
			stmt.execute(	"DROP TABLE branches CASCADE;"+
							"DROP TABLE accounts CASCADE;"+
							"DROP TABLE tellers CASCADE;"+
							"DROP TABLE history");	//besserer SQL-Befehl für Löschen?!
			stmt.execute("create table branches "+
									"(branchid serial not null,"+ 
									"branchname char(20) not null,"+ 
									"balance int not null,"+ 
									"address char(72) not null,"+ 
									"primary key (branchid) );");
			stmt.execute("create table accounts"+ 
									"(accid serial not null,"+ 
									"name char(20) not null,"+ 
									"balance int not null,"+ 
									"branchid int not null,"+ 
									"address char(68) not null,"+ 
									"primary key (accid),"+ 
									"foreign key (branchid) references branches);");
			stmt.execute("create table tellers"+ 
									"(tellerid serial not null,"+ 
									"tellername char(20) not null,"+ 
									"balance int not null,"+ 
									"branchid int not null,"+ 
									"address char(68) not null,"+ 
									"primary key (tellerid),"+ 
									"foreign key (branchid) references branches);");
			stmt.execute("create table history"+ 
									"(accid serial not null,"+ 
									"tellerid int not null,"+ 
									"delta int not null,"+ 
									"branchid int not null,"+ 
									"accbalance int not null,"+ 
									"cmmnt char(30) not null,"+ 
									"foreign key (accid) references accounts,"+ 
									"foreign key (tellerid) references tellers,"+ 
									"foreign key (branchid) references branches );");
		}
		catch(SQLException e)
		{
			System.err.println(e);
			System.exit(1);
		}
	} // ende Methode erstelleTabellen.
} // ende Klasse Initialisierung.

Wusste nicht in welches Forum das hier gehört
 
Das Beispiel ist etwas groß, um es mal schnell zu verstehen und den Fehler zu sehen. Woher weißt du denn, dass sie nicht parallel ablaufen? Sind sie vielleicht beide so schnell, dass du das gar nicht merkst?

Du könntest ja mal in einem explizit eine Sekunde pausieren und schauen, ob der andere trotzdem durchläuft.
 
Ich sehe das daran, dass ich am Ende des Threads eine Ausgabe ("Threadende") gehangen habe. Beide Thread starten zeitgleich, dann kommt irgendwann die erste Ausgabe und erst 5-6 Sekunden später die zweite Ausgabe. Das lässt mich darauf schließen, dass beide Threads nicht parallel laufen.
 
Hallo,

es kann sein, dass der eine Thread länger braucht. Füg doch mal zum Testen am Anfang der Threads eine Schleife ein, die etwas ausgibt:
Java:
for(int i = 0; i < 10; i++) {
  System.out.println(i);
}
Bei korrekter Nebenläufigkeit sind die Ausgaben ineinander verzahnt, das heißt man hat eine Zahlenfolge von zum Beispiel 0,0,1,2,1,2,3,3 usw. Wenn die Threads hintereinander ablaufen, dann ist die erste Zahlenfolge zuende, bevor die zweite angefangen hat.
 
Zuletzt bearbeitet:
Ich hab das Ganze mal eingefügt und bekomme folgendes geliefert: 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 8 9
Ist das jetzt nebenläufig oder nicht?
 
Zuletzt bearbeitet:
Dann laufen sie nebenläufig. Vielleicht verwendest du innerhalb der Threads eine Resource, die synchronized ist, weshalb nur einer zur Zeit sie benutzen darf und der andere Thread warten muss?
 

Neue Themen


Zurück
Oben