commit
e87cc8212b
19
README.adoc
19
README.adoc
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue