A no jak wchodzimy na terytoriów WTF bugów to:
package deadlocks;
public class Deadlock1 {
void method(String label) {
Boolean x = true;
synchronized (x) {
while (true) {
System.out.println("Running " + label);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Deadlock1 deadlock1 = new Deadlock1();
new Thread(() -> deadlock1.method("1")).start();
new Thread(() -> deadlock1.method("2")).start();
}
}
Co się wypisze na ekranie? :) W końcu synchronizacja na lokalnej zmiennej powinna w ogóle nie mieć wpływu na nic? ;)
I analogiczny kod ale jeśli zmienimy Boolean x = true;
na Boolean x = new Boolean(true);
(które to IntelliJ oznacza jako WTF i sugeruje zamienić z powrotem)
edit: i druga ciekawostka z życia wzięta:
package deadlocks;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Deadlock2 {
public static void main(String[] args) {
List<Integer> values = IntStream.range(0, 100).boxed().collect(Collectors.toList());
List<Integer> results = values.parallelStream() // paralell czyli szybciej? ;)
.map(Deadlock2::process)
.collect(Collectors.toList());
System.out.println(results);
}
private static Integer process(int x) {
System.out.println(Thread.currentThread() + " Entered " + x);
CompletableFuture<Integer> async = CompletableFuture.supplyAsync(() -> slowFunction(x)); // puszczamy w tle, a my cośtam dalej możemy sobie robić bo kiedyś nam sie to policzy...
while (!async.isDone()) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return async.join();
}
private static int slowFunction(int x) {
return x + 1;
}
}
Jak zadziała ten kod i czemu? I co się stanie jak zamienimy parallelStream
na stream
. W końcu paralell to powinien zadziałać szybciej, prawda? ;)