Merge pull request #1 from ZHAW-IT-PROG2-2022/master

Feedback
This commit is contained in:
romanschenk37 2022-03-06 22:06:37 +01:00 committed by GitHub
commit e87cc8212b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 200 additions and 21 deletions

View File

@ -81,6 +81,22 @@ Die Pflichtaufgabe wird mit 0 bis 2 Punkten bewertet (siehe _Leistungsnachweise_
.Thread Zustandsmodell (vereinfacht) .Thread Zustandsmodell (vereinfacht)
image::Thread-State-Model.png[pdfwidth=80%, width=900px] image::Thread-State-Model.png[pdfwidth=80%, width=900px]
==== Instanz einer Subklasse von Thread erstellen.
- muss Methode run() beinhalten.
- erstellen mit Thread myThread = new MyThread();
- starten mit new MyThread().start();
==== Interface Runnable implementieren
- muss Methode run() beinhalten.
- starten mit new Thread(new MyRunnable()).start();
==== Zustandswechsel
- Ready sobald run() aufgerufen wird.
- Running sobald scheduler den Thread ausführt.
- Zurück zu Ready mit t.yield() wird durch scheduler ausgeführt.
- manuell pausieren mit: t.join(), t.sleep(time), t.join(timeout)
- endet automatisch sobald die Methode run() fertig ausgeführt ist.
=== Printer-Threads: Verwendung von Java Threads [PU] === Printer-Threads: Verwendung von Java Threads [PU]
Nachfolgend einige Basisübungen zum Starten und Stoppen von Threads in Java. Nachfolgend einige Basisübungen zum Starten und Stoppen von Threads in Java.
@ -154,8 +170,11 @@ Wenn nötig, geben Sie auch die Konfiguration des Thread-Pools an.
[loweralpha] [loweralpha]
. Sie schreiben einen Server, der via Netzwerk Anfragen erhält. Jede Anfrage soll in einem eigenen Task beantwortet werden. Die Anzahl gleichzeitiger Anfragen schwankt über den Tag verteilt stark. . Sie schreiben einen Server, der via Netzwerk Anfragen erhält. Jede Anfrage soll in einem eigenen Task beantwortet werden. Die Anzahl gleichzeitiger Anfragen schwankt über den Tag verteilt stark.
- CachedThreadPool
. Ihr Graphikprogramm verwendet komplexe Mathematik um von hunderten von Objekten die Position, Geschwindigkeit und scheinbare Grösse (aus Sicht des Betrachters) zu berechnen und auf dem Bildschirm darzustellen. . Ihr Graphikprogramm verwendet komplexe Mathematik um von hunderten von Objekten die Position, Geschwindigkeit und scheinbare Grösse (aus Sicht des Betrachters) zu berechnen und auf dem Bildschirm darzustellen.
- SingleThreadExecutor
. Je nach Datenset sind unterschiedliche Algorithmen schneller in der Berechnung des Resultats (z.B. Sortierung). Sie möchten jedoch in jedem Fall immer so schnell wie möglich das Resultat haben und lassen deshalb mehrere Algorithmen parallel arbeiten. . Je nach Datenset sind unterschiedliche Algorithmen schneller in der Berechnung des Resultats (z.B. Sortierung). Sie möchten jedoch in jedem Fall immer so schnell wie möglich das Resultat haben und lassen deshalb mehrere Algorithmen parallel arbeiten.
- FixedThreadPool
=== Prime Checker [PU] === Prime Checker [PU]

View File

@ -11,6 +11,7 @@ import java.util.concurrent.*;
public class MandelbrotCallableProcessor extends MandelbrotProcessor { public class MandelbrotCallableProcessor extends MandelbrotProcessor {
private volatile boolean terminate; // signal the threads to abort processing and terminate private volatile boolean terminate; // signal the threads to abort processing and terminate
ExecutorService executorService;
/** /**
* Initialize the Mandelbrot processor. * Initialize the Mandelbrot processor.
@ -38,9 +39,13 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
super.startTime = System.currentTimeMillis(); super.startTime = System.currentTimeMillis();
// TODO: Start the the executor service with the given number of threads. // TODO: Start the the executor service with the given number of threads.
executorService = Executors.newFixedThreadPool(numThreads);
// TODO: process all rows using the Callable MandelbrotTask and store returned Futures in a list // TODO: process all rows using the Callable MandelbrotTask and store returned Futures in a list
List<Future<ImageRow>> futures = new ArrayList<>();
for(int row = 0; row < height; row ++) {
futures.add(executorService.submit(new MandelbrotTask(row)));
}
@ -51,11 +56,14 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
// TODO: get results from Future list and send them to the processListener (GUI) // TODO: get results from Future list and send them to the processListener (GUI)
// make sure to handle all Exceptions // make sure to handle all Exceptions
try { try {
for(Future<ImageRow> future : futures) {
processorListener.rowProcessed(future.get());
}
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally { } finally {
// stop processing and shutdown executor // stop processing and shutdown executor
stopProcessing(); stopProcessing();
@ -70,7 +78,7 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
public void stopProcessing() { public void stopProcessing() {
terminate = true; // signal the threads to abort terminate = true; // signal the threads to abort
// TODO: shutdown executor service // TODO: shutdown executor service
executorService.shutdown();
// calculate processing time // calculate processing time
@ -93,10 +101,49 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
private class MandelbrotTask implements Callable<ImageRow> { private class MandelbrotTask implements Callable<ImageRow> {
// TODO: Use Task implementation from MandelbrotExecutorProcessor change it to a Callable. // TODO: Use Task implementation from MandelbrotExecutorProcessor change it to a Callable.
private final int row;
private final double xmin, xmax, ymin, ymax, dx, dy;
private final int maxIterations;
public ImageRow call() { MandelbrotTask(int row) {
return null; // Compute one row of pixels. this.row = row;
xmin = -1.6744096740931858;
xmax = -1.674409674093473;
ymin = 4.716540768697223E-5;
ymax = 4.716540790246652E-5;
dx = (xmax - xmin) / (width - 1);
dy = (ymax - ymin) / (height - 1);
maxIterations = 10000;
} }
@Override
public ImageRow call() {
// Compute one row of pixels.
final ImageRow imageRow = new ImageRow(row, width);
double x;
double y = ymax - dy * row;
for (int col = 0; col < width; col++) {
x = xmin + dx * col;
int count = 0;
double xx = x;
double yy = y;
while (count < maxIterations && (xx * xx + yy * yy) < 4) {
count++;
double newxx = xx * xx - yy * yy + x;
yy = 2 * xx * yy + y;
xx = newxx;
}
// select color based on count of iterations
imageRow.pixels[col] = (count != maxIterations) ?
palette[count % palette.length] : Color.BLACK;
}
return imageRow;
}
} // end MandelbrotTask } // end MandelbrotTask
} }

View File

@ -10,7 +10,7 @@ import java.util.concurrent.Executors;
public class MandelbrotExecutorProcessor extends MandelbrotProcessor { public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
private volatile boolean terminate; // signal the threads to abort processing and terminate private volatile boolean terminate; // signal the threads to abort processing and terminate
private ExecutorService executorService;
/** /**
* Initialize the Mandelbrot processor. * Initialize the Mandelbrot processor.
@ -39,8 +39,17 @@ public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
// TODO: Start the the executor service with the given number of threads. // TODO: Start the the executor service with the given number of threads.
executorService = Executors.newFixedThreadPool(numThreads);
// TODO: start a task for each row // TODO: start a task for each row
for(int row = 0; row < height; row ++) {
executorService.execute(new MandelbrotExecutorProcessor.MandelbrotTask(row));
}
@ -54,6 +63,7 @@ public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
public void stopProcessing() { public void stopProcessing() {
terminate = true; // signal the threads to abort terminate = true; // signal the threads to abort
// TODO: shutdown executor service // TODO: shutdown executor service
executorService.shutdown();
// calculate processing time // calculate processing time
long duration = System.currentTimeMillis() - startTime; long duration = System.currentTimeMillis() - startTime;
@ -72,9 +82,45 @@ public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
private class MandelbrotTask implements Runnable { private class MandelbrotTask implements Runnable {
// TODO: Use Task implementation from MandelbrotTaskProcessor and modify it to calculat only one row. // TODO: Use Task implementation from MandelbrotTaskProcessor and modify it to calculat only one row.
private final int row;
private final double xmin, xmax, ymin, ymax, dx, dy;
private final int maxIterations;
MandelbrotTask(int row) {
this.row = row;
xmin = -1.6744096740931858;
xmax = -1.674409674093473;
ymin = 4.716540768697223E-5;
ymax = 4.716540790246652E-5;
dx = (xmax - xmin) / (width - 1);
dy = (ymax - ymin) / (height - 1);
maxIterations = 10000;
}
@Override @Override
public void run() { public void run() {
final ImageRow imageRow = new ImageRow(row, width);
double x;
double y = ymax - dy * row;
for (int col = 0; col < width; col++) {
x = xmin + dx * col;
int count = 0;
double xx = x;
double yy = y;
while (count < maxIterations && (xx * xx + yy * yy) < 4) {
count++;
double newxx = xx * xx - yy * yy + x;
yy = 2 * xx * yy + y;
xx = newxx;
}
// select color based on count of iterations
imageRow.pixels[col] = (count != maxIterations) ?
palette[count % palette.length] : Color.BLACK;
}
processorListener.rowProcessed(imageRow);
taskFinished();
} }
} // end MandelbrotTask } // end MandelbrotTask
} }

View File

@ -21,7 +21,7 @@ public class PrimeChecker {
private static void checkPrimes(int numPrimes) throws InterruptedException { private static void checkPrimes(int numPrimes) throws InterruptedException {
for (int i = 0; i < numPrimes; i++) { for (int i = 0; i < numPrimes; i++) {
new PrimeTask(nextRandom()).run(); // runs sequential in current thread new Thread(new PrimeTask(nextRandom())).start(); // runs sequential in current thread
} }
} }

View File

@ -2,6 +2,7 @@ package ch.zhaw.prog2.primechecker;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class PrimeCheckerExecutor { public class PrimeCheckerExecutor {
@ -25,15 +26,16 @@ public class PrimeCheckerExecutor {
private static void checkPrimes(int numPrimes) throws InterruptedException { private static void checkPrimes(int numPrimes) throws InterruptedException {
// TODO: create ExecutorService - What ThreadPool-Type/-Size fits best? // TODO: create ExecutorService - What ThreadPool-Type/-Size fits best?
ExecutorService executor = Executors.newFixedThreadPool(12);
for (int i = 0; i < numPrimes; i++) { for (int i = 0; i < numPrimes; i++) {
// TODO: execute the runnable using the executor service // TODO: execute the runnable using the executor service
executor.execute(new PrimeTask(nextRandom()));
} }
// stop ExecutorService // TODO: stop ExecutorService
executor.shutdown();
// wait for termination with timeout of 1 minute // TODO: wait for termination with timeout of 1 minute
executor.awaitTermination(1, TimeUnit.MINUTES);
} }
private static long nextRandom() { private static long nextRandom() {

View File

@ -25,19 +25,26 @@ public class PrimeCheckerFuture {
private static void checkPrimes(int numPrimes) throws InterruptedException { private static void checkPrimes(int numPrimes) throws InterruptedException {
// TODO: create ExecutorService // TODO: create ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(12);
// TODO: submit tasks to ExecutorService and collect the returned Futures in a List // TODO: submit tasks to ExecutorService and collect the returned Futures in a List
List<Future<PrimeTaskCallable.Result>> futures = new ArrayList<>();
for (int i = 0; i < numPrimes; i++) { for (int i = 0; i < numPrimes; i++) {
futures.add(executor.submit(new PrimeTaskCallable(nextRandom())));
} }
// TODO: Loop through List, wait for completion and print results // TODO: Loop through List, wait for completion and print results
for(Future<PrimeTaskCallable.Result> future : futures){
try {
System.out.println(future.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// TODO: stop ExecutorService // TODO: stop ExecutorService
executor.shutdown();
// TODO: await termination with timeout 1 minute // TODO: await termination with timeout 1 minute
executor.awaitTermination(1, TimeUnit.MINUTES);
} }
private static long nextRandom() { private static long nextRandom() {

View File

@ -12,7 +12,7 @@ public class PrimeTaskCallable implements Callable<PrimeTaskCallable.Result> {
public Result call() { public Result call() {
return null; return new Result(primeCandidate, findSmallestFactor(primeCandidate));
} }
/** /**
@ -47,5 +47,14 @@ public class PrimeTaskCallable implements Callable<PrimeTaskCallable.Result> {
this.factor = factor; this.factor = factor;
this.isPrime = factor == 0; this.isPrime = factor == 0;
} }
@Override
public String toString() {
return "Result{" +
"candidate=" + candidate +
", factor=" + factor +
", isPrime=" + isPrime +
'}';
}
} }
} }

View File

@ -15,6 +15,7 @@ public class Printer {
private static class PrinterThread extends Thread { private static class PrinterThread extends Thread {
char symbol; char symbol;
int sleepTime; int sleepTime;
Thread current_thread = this;
public PrinterThread(String name, char symbol, int sleepTime) { public PrinterThread(String name, char symbol, int sleepTime) {
super(name); super(name);
@ -24,6 +25,9 @@ public class Printer {
@Override @Override
public void run() { public void run() {
if(Thread.currentThread() != current_thread){
return;
}
System.out.println(getName() + " run started..."); System.out.println(getName() + " run started...");
for (int i = 1; i < 100; i++) { for (int i = 1; i < 100; i++) {
System.out.print(symbol); System.out.print(symbol);

View File

@ -0,0 +1,45 @@
package ch.zhaw.prog2.printer;
public class PrinterB {
// test program
public static void main(String[] arg) throws InterruptedException {
Thread threadA = new Thread(new PrinterRunnable("PrinterA", '.', 10));
threadA.start();
Thread threadB = new Thread(new PrinterRunnable("PrinterB", '*', 20));
threadB.start();
while(threadA.isAlive() || threadB.isAlive()){
Thread.sleep(10);
}
System.out.println("Ende Main Thread asdf");
}
private static class PrinterRunnable implements Runnable {
char symbol;
int sleepTime;
String name;
public PrinterRunnable(String name, char symbol, int sleepTime) {
this.name = name;
this.symbol = symbol;
this.sleepTime = sleepTime;
}
@Override
public void run() {
System.out.println(name + " run started...");
for (int i = 1; i < 100; i++) {
System.out.print(symbol);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println('\n' + name + " run ended.");
}
}
}