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)
|
||||
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]
|
||||
|
||||
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]
|
||||
. 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.
|
||||
- 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.
|
||||
- FixedThreadPool
|
||||
|
||||
=== Prime Checker [PU]
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.concurrent.*;
|
|||
public class MandelbrotCallableProcessor extends MandelbrotProcessor {
|
||||
|
||||
private volatile boolean terminate; // signal the threads to abort processing and terminate
|
||||
ExecutorService executorService;
|
||||
|
||||
/**
|
||||
* Initialize the Mandelbrot processor.
|
||||
|
@ -38,9 +39,13 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
|
|||
super.startTime = System.currentTimeMillis();
|
||||
|
||||
// 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
|
||||
|
||||
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)
|
||||
// make sure to handle all Exceptions
|
||||
try {
|
||||
for(Future<ImageRow> future : futures) {
|
||||
processorListener.rowProcessed(future.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// stop processing and shutdown executor
|
||||
stopProcessing();
|
||||
|
@ -70,7 +78,7 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
|
|||
public void stopProcessing() {
|
||||
terminate = true; // signal the threads to abort
|
||||
// TODO: shutdown executor service
|
||||
|
||||
executorService.shutdown();
|
||||
|
||||
|
||||
// calculate processing time
|
||||
|
@ -93,10 +101,49 @@ public class MandelbrotCallableProcessor extends MandelbrotProcessor {
|
|||
private class MandelbrotTask implements Callable<ImageRow> {
|
||||
// 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() {
|
||||
return null; // Compute one row of pixels.
|
||||
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
|
||||
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
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.concurrent.Executors;
|
|||
public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
|
||||
|
||||
private volatile boolean terminate; // signal the threads to abort processing and terminate
|
||||
|
||||
private ExecutorService executorService;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
executorService = Executors.newFixedThreadPool(numThreads);
|
||||
|
||||
|
||||
// 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() {
|
||||
terminate = true; // signal the threads to abort
|
||||
// TODO: shutdown executor service
|
||||
executorService.shutdown();
|
||||
|
||||
// calculate processing time
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
|
@ -72,9 +82,45 @@ public class MandelbrotExecutorProcessor extends MandelbrotProcessor {
|
|||
private class MandelbrotTask implements Runnable {
|
||||
// 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
|
||||
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
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class PrimeChecker {
|
|||
|
||||
private static void checkPrimes(int numPrimes) throws InterruptedException {
|
||||
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.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class PrimeCheckerExecutor {
|
||||
|
@ -25,15 +26,16 @@ public class PrimeCheckerExecutor {
|
|||
|
||||
private static void checkPrimes(int numPrimes) throws InterruptedException {
|
||||
// TODO: create ExecutorService - What ThreadPool-Type/-Size fits best?
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(12);
|
||||
for (int i = 0; i < numPrimes; i++) {
|
||||
// TODO: execute the runnable using the executor service
|
||||
|
||||
executor.execute(new PrimeTask(nextRandom()));
|
||||
}
|
||||
// stop ExecutorService
|
||||
|
||||
// wait for termination with timeout of 1 minute
|
||||
|
||||
// TODO: stop ExecutorService
|
||||
executor.shutdown();
|
||||
// TODO: wait for termination with timeout of 1 minute
|
||||
executor.awaitTermination(1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private static long nextRandom() {
|
||||
|
|
|
@ -25,19 +25,26 @@ public class PrimeCheckerFuture {
|
|||
|
||||
private static void checkPrimes(int numPrimes) throws InterruptedException {
|
||||
// TODO: create ExecutorService
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(12);
|
||||
|
||||
// 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++) {
|
||||
|
||||
futures.add(executor.submit(new PrimeTaskCallable(nextRandom())));
|
||||
}
|
||||
// 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
|
||||
|
||||
executor.shutdown();
|
||||
// TODO: await termination with timeout 1 minute
|
||||
|
||||
executor.awaitTermination(1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private static long nextRandom() {
|
||||
|
|
|
@ -12,7 +12,7 @@ public class PrimeTaskCallable implements Callable<PrimeTaskCallable.Result> {
|
|||
|
||||
|
||||
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.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 {
|
||||
char symbol;
|
||||
int sleepTime;
|
||||
Thread current_thread = this;
|
||||
|
||||
public PrinterThread(String name, char symbol, int sleepTime) {
|
||||
super(name);
|
||||
|
@ -24,6 +25,9 @@ public class Printer {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
if(Thread.currentThread() != current_thread){
|
||||
return;
|
||||
}
|
||||
System.out.println(getName() + " run started...");
|
||||
for (int i = 1; i < 100; i++) {
|
||||
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