58
07. Bonus - Puzzlers Программирование на Java Федор Лаврентьев МФТИ, 2016

Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Embed Size (px)

Citation preview

Page 1: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

07. Bonus - PuzzlersПрограммирование на Java

Федор ЛаврентьевМФТИ, 2016

Page 2: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Синхронизация

Page 3: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

BitSet refreshingBitSet bitSet = new BitSet(2);CountDownLatch latch = new CountDownLatch(1);

Thread t1 = new Thread(() -> { latch.await(); Thread.sleep(1000); bitSet.set(0);});

Thread t2 = new Thread(() -> { latch.await(); Thread.sleep(1000); bitSet.set(1);});

t1.start(); t2.start(); latch.countDown(); t1.join(); t2.join();

System.out.println(bitSet.get(0) + " " + bitSet.get(1));

Page 4: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

BitSet refreshingBitSet bitSet = new BitSet(2);CountDownLatch latch = new CountDownLatch(1);

Thread t1 = new Thread(() -> { latch.await(); Thread.sleep(1000); bitSet.set(0);});

Thread t2 = new Thread(() -> { latch.await(); Thread.sleep(1000); bitSet.set(1);});

t1.start(); t2.start(); latch.countDown(); t1.join(); t2.join();

System.out.println(bitSet.get(0) + " " + bitSet.get(1)); // true false

Page 5: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

BitSet refreshingBitSet bitSet = new BitSet(2);CountDownLatch latch = new CountDownLatch(1);

Thread t1 = new Thread(() -> { latch.await(); Thread.sleep(1000); synchronized(bitSet) {bitSet.set(0);}});

Thread t2 = new Thread(() -> { latch.await(); Thread.sleep(1000); synchronized(bitSet) {bitSet.set(1);} });

t1.start(); t2.start(); latch.countDown(); t1.join(); t2.join();

System.out.println(bitSet.get(0) + " " + bitSet.get(1)); // true true

Page 6: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Diggers must digprivate 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/

Page 7: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Diggers must digprivate 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/

Page 8: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Diggers must digprivate 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/

Page 9: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Parallel appendsList<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/

Page 10: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Parallel appendsList<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/

Page 11: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Parallel appendsList<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/

Page 12: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Parallel appendsList<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/

Page 13: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Name yourselfstatic 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/

Page 14: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Name yourselfstatic 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/

Page 15: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Name yourselfstatic 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/

Page 16: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Name yourselfstatic 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/

Page 17: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Примитивы

Page 18: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Java Puzzlers• Joshua Bloch, Neal Gafter “Java Puzzlers”• http://www.javapuzzlers.com/

Page 19: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Long divisionlong MICROS = 24 * 60 * 60 * 1000 * 1000;long MILLIS = 24 * 60 * 60 * 1000;System.out.println(MICROS / MILLIS);

Page 20: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Long divisionlong MICROS = 24 * 60 * 60 * 1000 * 1000;long MILLIS = 24 * 60 * 60 * 1000;System.out.println(MICROS / MILLIS); // 5 WTF?

Page 21: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Long divisionlong MICROS = 24L * 60 * 60 * 1000 * 1000;long MILLIS = 24L * 60 * 60 * 1000;System.out.println(MICROS / MILLIS); // 1000

Page 22: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

CafebabeSystem.out.println( Long.toHexString(0x100000000L + 0xcafebabe));

Page 23: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

CafebabeSystem.out.println( Long.toHexString(0x1_0000_0000L + 0xcafe_babe));

Page 24: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

CafebabeSystem.out.println( Long.toHexString(0x1_0000_0000L + 0xcafe_babe)); // 0xcafebabe ?!

Page 25: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

CafebabeSystem.out.println( Long.toHexString(0x1_0000_0000L + 0xcafe_babe));

// 0x1_0000_0000 = 0x0000_0001_0000_0000// 0xcafebabe = -889275714 = 0xcafe_babe

Page 26: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

CafebabeSystem.out.println( Long.toHexString(0x1_0000_0000L + 0xcafe_babe));

// 0x1_0000_0000 = 0x0000_0001_0000_0000// +// -889275714 = 0xffff_ffff_cafe_babe// =// 0x0000_0000_cafe_babe

Page 27: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

A big delight in every bytefor (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { if (b == 0x90) { System.out.println(“Gotcha!”) }}

Page 28: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

A big delight in every bytefor (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { if (b == 0x90) { System.out.println(“Gotcha!”) }} // Nope... =(

Page 29: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

A big delight in every bytefor (byte b = Byte.MIN_VALUE; // -127 b < Byte.MAX_VALUE; // 128 b++) { if (b == 0x90) { // ((int) b == 144) System.out.println(“Gotcha!”) }}

Page 30: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Inclement Incrementint j = 0;for (int i = 0; i < 100; i++) { j = j++;}System.out.println(j);

Page 31: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Inclement Incrementint j = 0;for (int i = 0; i < 100; i++) { j = j++;}System.out.println(j); // 0

Page 32: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Inclement Incrementint j = 0;for (int i = 0; i < 100; i++) { j_temp = j; j = j + 1; j = j_temp;}System.out.println(j);

Page 33: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Исключения

Page 34: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Indecisionstatic boolean decision() { try { return true; } finally { return false; }}

public static void main(String[] args) { System.out.println(decision());}

Page 35: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Indecisionstatic boolean decision() { try { return true; } finally { return false; }}

public static void main(String[] args) { System.out.println(decision());} // false

Page 36: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Indecisionstatic boolean decision() { try { return true; } finally { return false; // More important }}

public static void main(String[] args) { System.out.println(decision());} // false

Page 37: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Hello, Goodbyetry { System.out.println("Hello world"); System.exit(0);} finally { System.out.println("Goodbye world");}

Page 38: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Hello, Goodbyetry { System.out.println("Hello world"); System.exit(0);} finally { System.out.println("Goodbye world");} // Hello, world...

Page 39: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Hello, Goodbyetry { System.out.println("Hello world"); System.exit(0); // Shutdowns JVM} finally { System.out.println("Goodbye world");}

Page 40: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Reluctantpublic class Reluctant { private Reluctant internalInstance = new Reluctant();

public Reluctant() throws Exception { throw new Exception("Don't touch me!"); }

public static void main(String[] args) { try { Reluctant b = new Reluctant(); System.out.println("Oh, man..."); } catch (Exception ex) { System.out.println("I told you so!"); } }}

Page 41: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Reluctantpublic class Reluctant { private Reluctant internalInstance = new Reluctant();

public Reluctant() throws Exception { throw new Exception("Don't touch me!"); }

public static void main(String[] args) { try { Reluctant b = new Reluctant(); System.out.println("Oh, man..."); } catch (Exception ex) { System.out.println("I told you so!"); } } // StackOverflowError}

Page 42: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Reluctantpublic class Reluctant { private Reluctant internalInstance = new Reluctant();

public Reluctant() throws Exception { throw new Exception("Don't touch me!"); }

public static void main(String[] args) { try { Reluctant b = new Reluctant(); System.out.println("Oh, man..."); } catch (Exception ex) { System.out.println("I told you so!"); } }}

Page 43: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Классы

Page 44: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Confusing overloadpublic 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); }}

Page 45: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Confusing overloadpublic 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 }}

Page 46: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Confusing overloadpublic 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}

Page 47: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Confusing overloadpublic 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); }}

Page 48: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Confusing overloadpublic 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 }}

Page 49: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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");}

Page 50: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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}

Page 51: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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");}

Page 52: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Larger than lifepublic 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."); } }

Page 53: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Larger than lifepublic 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}

Page 54: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Larger than lifepublic 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."); } }

Page 55: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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")); }}

Page 56: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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”}

Page 57: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

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 }}

Page 58: Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor