Курс "Программирование на Java". Лекция 07 "Бонус - Головоломки".
Java Puzzlers. Синхронизация и многопоточность. Примитивы. Объекты и классы. Исключения и финализация.
МФТИ, 2016 год. Лектор - Лаврентьев Федор Сергеевич
6. Diggers must dig
private static boolean stop = false;
public static void main(String[] args) {
Thread timer = new Thread(() -> {
Thread.sleep(1000);
stop = true;
});
timer.start();
while (!stop)
/* do nothing */;
}
https://mlangc.wordpress.com/2011/05/10/series-about-java-concurrency-pt-3/
7. Diggers must dig
private static boolean stop = false;
public static void main(String[] args) {
Thread timer = new Thread(() -> {
Thread.sleep(1000);
stop = true;
});
timer.start();
while (!stop) // cached: stop == false
/* do nothing */;
} // Never stops
https://mlangc.wordpress.com/2011/05/10/series-about-java-concurrency-pt-3/
8. Diggers must dig
private static volatile boolean stop = false;
public static void main(String[] args) {
Thread timer = new Thread(() -> {
Thread.sleep(1000);
stop = true;
});
timer.start();
while (!stop)
/* do nothing */;
} // Stops in 1000 ms
https://mlangc.wordpress.com/2011/05/10/series-about-java-concurrency-pt-3/
9. Parallel appends
List<Integer> list = null;
private class Action implements Runnable {
private final int data;
public void run() {
synchronized (this) {
if (list == null) list = new CopyOnWriteArrayList<>();
}
list.add(data);
}
}
final int NTHREADS = 8; Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i != NTHREADS; ++i) threads[i] = new Thread(new Action(i));
for (int i = 0; i != NTHREADS; ++i) threads[i].start();
for (int i = 0; i != NTHREADS; ++i) threads[i].join();
System.out.println(list.size());
https://mlangc.wordpress.com/2009/11/27/series-about-java-concurrency-pt-1/
10. Parallel appends
List<Integer> list = null;
private class Action implements Runnable {
private final int data;
public void run() {
synchronized (this) {
if (list == null) list = new CopyOnWriteArrayList<>();
}
list.add(data);
}
}
final int NTHREADS = 8; Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i != NTHREADS; ++i) threads[i] = new Thread(new Action(i));
for (int i = 0; i != NTHREADS; ++i) threads[i].start();
for (int i = 0; i != NTHREADS; ++i) threads[i].join();
System.out.println(list.size()); // 1... 2... 3...
https://mlangc.wordpress.com/2009/11/27/series-about-java-concurrency-pt-1/
11. Parallel appends
List<Integer> list = null;
private class Action implements Runnable {
private final int data;
public void run() {
synchronized (Action.this) {
if (list == null) list = new CopyOnWriteArrayList<>();
}
list.add(data);
}
}
final int NTHREADS = 8; Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i != NTHREADS; ++i) threads[i] = new Thread(new Action(i));
for (int i = 0; i != NTHREADS; ++i) threads[i].start();
for (int i = 0; i != NTHREADS; ++i) threads[i].join();
System.out.println(list.size()); // 1... 2... 3...
https://mlangc.wordpress.com/2009/11/27/series-about-java-concurrency-pt-1/
12. Parallel appends
List<Integer> list = null;
private class Action implements Runnable {
private final int data;
public void run() {
synchronized (MyClass.this) {
if (list == null) list = new CopyOnWriteArrayList<>();
}
list.add(data);
}
}
final int NTHREADS = 8; Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i != NTHREADS; ++i) threads[i] = new Thread(new Action(i));
for (int i = 0; i != NTHREADS; ++i) threads[i].start();
for (int i = 0; i != NTHREADS; ++i) threads[i].join();
System.out.println(list.size()); // strictly 8
https://mlangc.wordpress.com/2009/11/27/series-about-java-concurrency-pt-1/
13. Name yourself
static final ThreadLocal<String> THREAD_NAME = new ThreadLocal<>();
static class NamingThread extends Thread {
private final int number;
public NamingThread(int number) {
this.number = number;
}
@Override
public void start() {
THREAD_NAME.set("Thread-" + number);
}
}
public static void main(String[] args) throws InterruptedException {
THREAD_NAME.set("Daddy"); int NTHREADS = 8;
Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i < NTHREADS; ++i) threads[i] = new NamingThread(i);
for (int i = 0; i < NTHREADS; ++i) threads[i].start();
for (int i = 0; i < NTHREADS; ++i) threads[i].join();
System.out.print(THREAD_NAME.get());
}
https://mlangc.wordpress.com/2013/02/13/series-about-java-concurrency-pt-5/
14. Name yourself
static final ThreadLocal<String> THREAD_NAME = new ThreadLocal<>();
static class NamingThread extends Thread {
private final int number;
public NamingThread(int number) {
this.number = number;
}
@Override
public void start() {
THREAD_NAME.set("Thread-" + number);
}
}
public static void main(String[] args) throws InterruptedException {
THREAD_NAME.set("Daddy"); int NTHREADS = 8;
Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i < NTHREADS; ++i) threads[i] = new NamingThread(i);
for (int i = 0; i < NTHREADS; ++i) threads[i].start();
for (int i = 0; i < NTHREADS; ++i) threads[i].join();
System.out.print(THREAD_NAME.get()); // Thread-7
}
https://mlangc.wordpress.com/2013/02/13/series-about-java-concurrency-pt-5/
15. Name yourself
static final ThreadLocal<String> THREAD_NAME = new ThreadLocal<>();
static class NamingThread extends Thread {
private final int number;
public NamingThread(int number) {
this.number = number;
}
@Override
public void start() {
THREAD_NAME.set("Thread-" + number);
}
}
public static void main(String[] args) throws InterruptedException {
THREAD_NAME.set("Daddy"); int NTHREADS = 8;
Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i < NTHREADS; ++i) threads[i] = new NamingThread(i);
for (int i = 0; i < NTHREADS; ++i) threads[i].start();
for (int i = 0; i < NTHREADS; ++i) threads[i].join();
System.out.print(THREAD_NAME.get());
}
https://mlangc.wordpress.com/2013/02/13/series-about-java-concurrency-pt-5/
16. Name yourself
static final ThreadLocal<String> THREAD_NAME = new ThreadLocal<>();
static class NamingThread extends Thread {
private final int number;
public NamingThread(int number) {
this.number = number;
}
@Override
public void run() {
THREAD_NAME.set("Thread-" + number);
}
}
public static void main(String[] args) throws InterruptedException {
THREAD_NAME.set("Daddy"); int NTHREADS = 8;
Thread[] threads = new Thread[NTHREADS];
for (int i = 0; i < NTHREADS; ++i) threads[i] = new NamingThread(i);
for (int i = 0; i < NTHREADS; ++i) threads[i].start();
for (int i = 0; i < NTHREADS; ++i) threads[i].join();
System.out.print(THREAD_NAME.get()); // Daddy
}
https://mlangc.wordpress.com/2013/02/13/series-about-java-concurrency-pt-5/
27. A big delight in every byte
for (byte b = Byte.MIN_VALUE;
b < Byte.MAX_VALUE;
b++) {
if (b == 0x90) {
System.out.println(“Gotcha!”)
}
}
28. A big delight in every byte
for (byte b = Byte.MIN_VALUE;
b < Byte.MAX_VALUE;
b++) {
if (b == 0x90) {
System.out.println(“Gotcha!”)
}
} // Nope... =(
29. A big delight in every byte
for (byte b = Byte.MIN_VALUE; // -127
b < Byte.MAX_VALUE; // 128
b++) {
if (b == 0x90) { // ((int) b == 144)
System.out.println(“Gotcha!”)
}
}
44. Confusing overload
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
45. Confusing overload
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null); // double array
}
}
46. Confusing overload
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null); // double array
} // double[] extends Object
}
47. Confusing overload
public class Confusing {
private Confusing(int[] iArray) {
System.out.println(”int array");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
48. Confusing overload
public class Confusing {
private Confusing(int[] iArray) {
System.out.println(”int array");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null); // doesn’t compile
}
}
49. Dog my cat!
class Counter {
private static int count = 0;
public static final synchronized void increment() {
count++;
}
public static final synchronized int getCount() {
return count;
}
}
class Dog extends Counter {
public void woof() { increment(); }
}
class Cat extends Counter {
public void meow() { increment(); }
}
public static void main(String[] args) {
Dog dogs[] = { new Dog(), new Dog() };
for (int i = 0; i < dogs.length; i++) dogs[i].woof();
Cat cats[] = { new Cat(), new Cat(), new Cat() };
for (int i = 0; i < cats.length; i++) cats[i].meow();
System.out.println(Dog.getCount() + " woofs");
System.out.println(Cat.getCount() + " meows");
}
50. Dog my cat!
class Counter {
private static int count = 0;
public static final synchronized void increment() {
count++;
}
public static final synchronized int getCount() {
return count;
}
}
class Dog extends Counter {
public void woof() { increment(); }
}
class Cat extends Counter {
public void meow() { increment(); }
}
public static void main(String[] args) {
Dog dogs[] = { new Dog(), new Dog() };
for (int i = 0; i < dogs.length; i++) dogs[i].woof();
Cat cats[] = { new Cat(), new Cat(), new Cat() };
for (int i = 0; i < cats.length; i++) cats[i].meow();
System.out.println(Dog.getCount() + " woofs"); // 5
System.out.println(Cat.getCount() + " meows"); // 5
}
51. Dog my cat!
class Counter {
private static int count = 0;
public static final synchronized void increment() {
count++;
}
public static final synchronized int getCount() {
return count;
}
}
class Dog extends Counter {
public void woof() { increment(); }
}
class Cat extends Counter {
public void meow() { increment(); }
}
public static void main(String[] args) {
Dog dogs[] = { new Dog(), new Dog() };
for (int i = 0; i < dogs.length; i++) dogs[i].woof();
Cat cats[] = { new Cat(), new Cat(), new Cat() };
for (int i = 0; i < cats.length; i++) cats[i].meow();
System.out.println(Dog.getCount() + " woofs");
System.out.println(Cat.getCount() + " meows");
}
52. Larger than life
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private final int beltSize;
private static final int CURRENT_YEAR =
Calendar.getInstance().get(Calendar.YEAR);
private Elvis() { beltSize = CURRENT_YEAR - 1930; }
public int beltSize() { return beltSize; }
public static void main(String[] args) {
System.out.println("Elvis wears a size " +
INSTANCE.beltSize() + " belt.");
}
}
53. Larger than life
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private final int beltSize;
private static final int CURRENT_YEAR =
Calendar.getInstance().get(Calendar.YEAR);
private Elvis() { beltSize = CURRENT_YEAR - 1930; }
public int beltSize() { return beltSize; }
public static void main(String[] args) {
System.out.println("Elvis wears a size " +
INSTANCE.beltSize() + " belt.");
} // -1930
}
54. Larger than life
public class Elvis {
public static final Elvis INSTANCE = new Elvis(); // 1
private final int beltSize;
private static final int CURRENT_YEAR = // 3
Calendar.getInstance().get(Calendar.YEAR);
private Elvis() { beltSize = CURRENT_YEAR - 1930; } // 2
public int beltSize() { return beltSize; }
public static void main(String[] args) {
System.out.println("Elvis wears a size " +
INSTANCE.beltSize() + " belt.");
}
}
55. What’s the point?
public class Point {
protected final int x, y;
private final String name;
Point(int x, int y) {
this.x = x;
this.y = y;
name = makeName();
}
protected String makeName() {
return "[" + x + "," + y + "]";
}
public final String toString() {
return name;
}
}
public class ColorPoint extends Point {
private final String color;
ColorPoint(int x, int y, String color) {
super(x, y);
this.color = color;
}
protected String makeName() {
return super.makeName() + ":" + color;
}
public static void main(String[] args) {
System.out.println(
new ColorPoint(4, 2, "purple"));
}
}
56. What’s the point?
public class Point {
protected final int x, y;
private final String name;
Point(int x, int y) {
this.x = x;
this.y = y;
name = makeName();
}
protected String makeName() {
return "[" + x + "," + y + "]";
}
public final String toString() {
return name;
}
}
public class ColorPoint extends Point {
private final String color;
ColorPoint(int x, int y, String color) {
super(x, y);
this.color = color;
}
protected String makeName() {
return super.makeName() + ":" + color;
}
public static void main(String[] args) {
System.out.println(
new ColorPoint(4, 2, "purple"));
} // “[4,2]:null”
}
57. What’s the point?
public class Point {
protected final int x, y;
private final String name;
Point(int x, int y) {
this.x = x; // 3
this.y = y; // 4
name = makeName(); // 5-10
}
protected String makeName() { // 7
return "[" + x + "," + y + "]"; // 8
}
public final String toString() {
return name;
}
}
public class ColorPoint extends Point {
private final String color;
ColorPoint(int x, int y, String color) {
super(x, y); // 2-11
this.color = color; // 12
}
protected String makeName() { // 6
return super.makeName() + ":" + color; // 7-9
}
public static void main(String[] args) {
System.out.println(
new ColorPoint(4, 2, "purple")); // 1-13
}
}