Gruppen 2 und 4
Samuel Teuber
propa@teuber.dev
https://teuber.dev/propa
synchronized(tasks) {
while (cond) {
try{
wait();
} catch (InterruptedException e) {}
}
}
IllegalMonitorStateException
Richtig:
synchronized(tasks) {
while (cond) {
try{
tasks.wait();
} catch (InterruptedException e) {}
}
}
AtomicInteger
¶The specifications of these methods enable implementations to employ efficient machine-level atomic instructions that are available on contemporary processors. However on some platforms, support may entail some form of internal locking. Thus the methods are not strictly guaranteed to be non-blocking -- a thread may block transiently before performing the operation.
Quelle: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
Geg.: Puffer
mydef = [1,3..]
mydef !! 10
mydef
ist ein Proxy der die Evaluation erst ausführt, wenn notwendig
Java:
Future<Integer> myfuture = executor.submit(() -> {
return returnComplicatedInt();
});
myfuture
ist ungefähr ein Proxy, der einen in der Zukunft auf das Ergebnis zugreifen lässt:
System.out.println(myfuture.get()); // blockiert bis Ergebnis
foldl max 0 (map (+1) [1,2,3,4,5])
Aktoren (Threads oder Prozesse) kommunizieren per Nachrichten
Wie MPI, aber:
Beispiel
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -1;
}
Umfrage
Program testing can be used to show the presence of bugs, but never to show their absence!
Edsger W. Dijkstra
Warum?
Syntax: Kommentare mit @ beginnend
boolean
==>
Implikation<==>
Äquivalenz<=!=>
XOR\old(expr)
Wert von expr vor Methode\result
Rückgabewertpublic int x;
public int y;
public int z;
/*@ requires y!=0;
@ ensures \old(y)+1 == y;
@ ensures x == \old(y);
@*/
public void doStuff() {
x = y++;
z = 10/x;
}
(\forall C x; B; R)
(\exists C x; B; R)
(\sum C x; B; R)
(\product C x; B; R)
(\max C x; B; R)
(\min C x; B; R)
(\num_of C x; B; R)
Diesmal R
numerischer Ausdruck bzw. Boolean (num_of
)
/*@
@ ???
@*/
void sort(int[] arr){/*...*/}
/*@ nullable @*/ List<Integer> list
assignable
für veränderbare Parameterassignable \nothing
class IntegerSet {
byte[] a; /* The arraya is sorted*
/*@
@ invariant (\forall int i;
@ 0 <= i && i < a.length-1;
@ a[i]< a[i+1]);
@*/
}
//...
public int doSth() {
this.i+=10;
return this.j;
}
/*@ requires a > 0
@ ensures doSth() = \old(a)
@*/
public void doSthElse(int a) {/*...*/}
//...
Geht das?
Nein! Denn doSth
hat Seiteneffekte.
Jede Funktion, die aus JML aufgerufen wird darf keine Seiteneffekte haben!
public /*@ pure @*/ int getBalance() {/*..*/}
/*@ requires a != null && 0 < a.length < Integer.MAX_VALUE;
@ requires (\forall int i; 0 <= i < a.length; (\forall int j; i < j < a.length; a[i] <= a[j]));
@ ensures (\exists int i; 0 <= i < a.length; a[i] == key) <==> a[\result]==key;
@ ensures !(\exists int i; 0 <= i < a.length; a[i] == key) <==> \result == -1;
@*/
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high-low) / 2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -1;
}
The moral is obvious. You can't trust code that you did not totally create yourself. (Especially code from com- panies that employ people like me.)
/*@ requires a != null && 0 < a.length < Integer.MAX_VALUE;
@ requires (\forall int i; 0 <= i < a.length; (\forall int j; i < j < a.length; a[i] <= a[j]));
@ ensures (\exists int i; 0 <= i < a.length; a[i] == key) <==> a[\result]==key;
@ ensures !(\exists int i; 0 <= i < a.length; a[i] == value) <==> \result == -1;
@ pure
@*/
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high-low) / 2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -1;
}
/*@ requires a != null && 0 < a.length < Integer.MAX_VALUE;
@ requires (\forall int i; 0 <= i < a.length; (\forall int j; i < j < a.length; a[i] <= a[j]));
@ ensures (\exists int i; 0 <= i < a.length; a[i] == key) <==> a[\result]==key;
@ ensures !(\exists int i; 0 <= i < a.length; a[i] == value) <==> \result == -1;
@ pure
@*/
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high-low) / 2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -1;
}
binarySearch(null,4);
/*@ requires a != null && 0 < a.length < Integer.MAX_VALUE;
@ requires (\forall int i; 0 <= i < a.length; (\forall int j; i < j < a.length; a[i] <= a[j]));
@ ensures (\exists int i; 0 <= i < a.length; a[i] == key) <==> a[\result]==key;
@ ensures !(\exists int i; 0 <= i < a.length; a[i] == value) <==> \result == -1;
@ pure
@*/
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high-low) / 2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1
else if (midVal > key)
high = mid - 1;
else
return mid+1;
}
return -1;
}
binarySearch(new int[]{1,2,3,4,5},4);
Barbara Liskov
Subtype Requirement:
Let $\Phi(x)$ be a property provable about objects $x$ of type $T$.
Then $\Phi(y)$ should be true for objects $y$ of type $S$ where $S$ is a subtype of $T$.
private/*@ spec_public@*/ int size = 0;
// ....
/*@ ensures \result!= null;
@ private behavior
@ requires size > 0;
@*/
Object pop() { /*...pop logic ...*/ }
Object pop() {
assert size > 0;
int _oldSize = size;
int _oldTop = top();
// pop logic
assert size == _oldSize-1;
assert result == _oldTop;
return result;
}