07. Bonus - Puzzlers
Программирование на Java
Федор Лаврентьев
МФТИ, 2016
Синхронизация
BitSet refreshing
BitSet 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));
BitSet refreshing
BitSet 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
BitSet refreshing
BitSet 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
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
Примитивы
Java Puzzlers
• Joshua Bloch, Neal Gafter “Java Puzzlers”
• http://www.javapuzzlers.com/
Long division
long MICROS = 24 * 60 * 60 * 1000 * 1000;
long MILLIS = 24 * 60 * 60 * 1000;
System.out.println(MICROS / MILLIS);
Long division
long MICROS = 24 * 60 * 60 * 1000 * 1000;
long MILLIS = 24 * 60 * 60 * 1000;
System.out.println(MICROS / MILLIS); // 5 WTF?
Long division
long MICROS = 24L * 60 * 60 * 1000 * 1000;
long MILLIS = 24L * 60 * 60 * 1000;
System.out.println(MICROS / MILLIS); // 1000
Cafebabe
System.out.println(
Long.toHexString(0x100000000L + 0xcafebabe)
);
Cafebabe
System.out.println(
Long.toHexString(0x1_0000_0000L + 0xcafe_babe)
);
Cafebabe
System.out.println(
Long.toHexString(0x1_0000_0000L + 0xcafe_babe)
); // 0xcafebabe ?!
Cafebabe
System.out.println(
Long.toHexString(0x1_0000_0000L + 0xcafe_babe)
);
// 0x1_0000_0000 = 0x0000_0001_0000_0000
// 0xcafebabe = -889275714 = 0xcafe_babe
Cafebabe
System.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
A big delight in every byte
for (byte b = Byte.MIN_VALUE;
b < Byte.MAX_VALUE;
b++) {
if (b == 0x90) {
System.out.println(“Gotcha!”)
}
}
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... =(
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!”)
}
}
Inclement Increment
int j = 0;
for (int i = 0; i < 100; i++) {
j = j++;
}
System.out.println(j);
Inclement Increment
int j = 0;
for (int i = 0; i < 100; i++) {
j = j++;
}
System.out.println(j); // 0
Inclement Increment
int j = 0;
for (int i = 0; i < 100; i++) {
j_temp = j;
j = j + 1;
j = j_temp;
}
System.out.println(j);
Исключения
Indecision
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
public static void main(String[] args) {
System.out.println(decision());
}
Indecision
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
public static void main(String[] args) {
System.out.println(decision());
} // false
Indecision
static boolean decision() {
try {
return true;
} finally {
return false; // More important
}
}
public static void main(String[] args) {
System.out.println(decision());
} // false
Hello, Goodbye
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
}
Hello, Goodbye
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
} // Hello, world...
Hello, Goodbye
try {
System.out.println("Hello world");
System.exit(0); // Shutdowns JVM
} finally {
System.out.println("Goodbye world");
}
Reluctant
public 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!");
}
}
}
Reluctant
public 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
}
Reluctant
public 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!");
}
}
}
Классы
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);
}
}
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
}
}
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
}
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);
}
}
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
}
}
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");
}
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
}
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");
}
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.");
}
}
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
}
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.");
}
}
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"));
}
}
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”
}
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
}
}
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor

  • 1.
    07. Bonus -Puzzlers Программирование на Java Федор Лаврентьев МФТИ, 2016
  • 2.
  • 3.
    BitSet refreshing BitSet 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));
  • 4.
    BitSet refreshing BitSet 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
  • 5.
    BitSet refreshing BitSet 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
  • 6.
    Diggers must dig privatestatic 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 privatestatic 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 privatestatic 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 finalThreadLocal<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 finalThreadLocal<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 finalThreadLocal<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 finalThreadLocal<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/
  • 17.
  • 18.
    Java Puzzlers • JoshuaBloch, Neal Gafter “Java Puzzlers” • http://www.javapuzzlers.com/
  • 19.
    Long division long MICROS= 24 * 60 * 60 * 1000 * 1000; long MILLIS = 24 * 60 * 60 * 1000; System.out.println(MICROS / MILLIS);
  • 20.
    Long division long MICROS= 24 * 60 * 60 * 1000 * 1000; long MILLIS = 24 * 60 * 60 * 1000; System.out.println(MICROS / MILLIS); // 5 WTF?
  • 21.
    Long division long MICROS= 24L * 60 * 60 * 1000 * 1000; long MILLIS = 24L * 60 * 60 * 1000; System.out.println(MICROS / MILLIS); // 1000
  • 22.
  • 23.
  • 24.
  • 25.
    Cafebabe System.out.println( Long.toHexString(0x1_0000_0000L + 0xcafe_babe) ); //0x1_0000_0000 = 0x0000_0001_0000_0000 // 0xcafebabe = -889275714 = 0xcafe_babe
  • 26.
    Cafebabe System.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
  • 27.
    A big delightin every byte for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { if (b == 0x90) { System.out.println(“Gotcha!”) } }
  • 28.
    A big delightin every byte for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { if (b == 0x90) { System.out.println(“Gotcha!”) } } // Nope... =(
  • 29.
    A big delightin 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!”) } }
  • 30.
    Inclement Increment int j= 0; for (int i = 0; i < 100; i++) { j = j++; } System.out.println(j);
  • 31.
    Inclement Increment int j= 0; for (int i = 0; i < 100; i++) { j = j++; } System.out.println(j); // 0
  • 32.
    Inclement Increment int j= 0; for (int i = 0; i < 100; i++) { j_temp = j; j = j + 1; j = j_temp; } System.out.println(j);
  • 33.
  • 34.
    Indecision static boolean decision(){ try { return true; } finally { return false; } } public static void main(String[] args) { System.out.println(decision()); }
  • 35.
    Indecision static boolean decision(){ try { return true; } finally { return false; } } public static void main(String[] args) { System.out.println(decision()); } // false
  • 36.
    Indecision static boolean decision(){ try { return true; } finally { return false; // More important } } public static void main(String[] args) { System.out.println(decision()); } // false
  • 37.
    Hello, Goodbye try { System.out.println("Helloworld"); System.exit(0); } finally { System.out.println("Goodbye world"); }
  • 38.
    Hello, Goodbye try { System.out.println("Helloworld"); System.exit(0); } finally { System.out.println("Goodbye world"); } // Hello, world...
  • 39.
    Hello, Goodbye try { System.out.println("Helloworld"); System.exit(0); // Shutdowns JVM } finally { System.out.println("Goodbye world"); }
  • 40.
    Reluctant public 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!"); } } }
  • 41.
    Reluctant public 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 }
  • 42.
    Reluctant public 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!"); } } }
  • 43.
  • 44.
    Confusing overload public classConfusing { 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 classConfusing { 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 classConfusing { 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 classConfusing { 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 classConfusing { 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! classCounter { 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! classCounter { 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! classCounter { 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 publicclass 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 publicclass 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 publicclass 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? publicclass 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? publicclass 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? publicclass 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 } }