Thursday, 12. February 2009
A few days ago, I registered stackoverflow.com and found an interesting post: what are hidden features of Java?
The stuffs that I didn’t know before are
- Double brace initialization
Map map=new HashMap<String,String>() {
{
put("key1","value1");
put("key2","value2");
}
};
Instance initializer
public class Initializer {
static {
System.out.println("static");
}
{
System.out.println("instance");
}
public Initializer() {
System.out.println("constructor");
}
}
Covariant return type
abstract class Base {
abstract List getList();
}
class Sub extends Base {
@Override
ArrayList getList() {
return null;
}
}
Double brace initialization uses instance initializer because first brace is for declairing annomymous inner class and second brace is for instance initializer block.
Tuesday, 20. January 2009
I saw a presentation on Java VM optimization via InfoQ. Java is originally slow, but HotSpot compiler is getting smarter enough to free Java from the shame.
http://www.infoq.com/presentations/pampuch-vm-optimizations-language-designers
Friday, 8. August 2008
Detecting deadlock is one of common features of Java profiling tools but I haven’t experienced the situation where those tools detect deadlock from code I wrote. In fact, deadlock is hazardous because it is difficult to predict and reproduce.
I wondered under what conditions do profilers detect deadlock and then report it, so I wrote code that reaches deadlock.
package com.grayger.deadlock;
public class SimpleDeadlocker {
private final static Object OBJ1=new Object();
private final static Object OBJ2=new Object();
private final static int LOOP=100;
public void obj1First() {
synchronized(OBJ1) {
printInfo("Hold OBJ1");
synchronized(OBJ2) {
printInfo("Hole OBJ2");
}
printInfo("Release OBJ2");
}
printInfo("Release OBJ1");
}
public void obj2First() {
synchronized(OBJ2) {
printInfo("Hold OBJ2");
synchronized(OBJ1) {
printInfo("Hole OBJ1");
}
printInfo("Release OBJ1");
}
printInfo("Release OBJ2");
}
private void printInfo(String info) {
System.out.println(Thread.currentThread().getName()+" "+info);
}
public static void main(String args[]) {
final SimpleDeadlocker d=new SimpleDeadlocker();
Thread t1=new Thread(new Runnable() {
public void run() {
for(int i=0;i<loop;i++)>
d.obj1First();
}
d.printInfo("Terminated");
}
}, "OBJ1_First");
Thread t2=new Thread(new Runnable() {
public void run() {
for(int i=0;i<loop;i++)>
d.obj2First();
}
d.printInfo("Terminated");
}
}, "OBJ2_First");
t1.start();
t2.start();
}
}
Above example can be refactored as follows:
package com.grayger.deadlock;
public class Deadlocker {
private final static int LOOP=100;
static class Deadlock1 {
private final static Object OBJ1=new Object();
private final static Object OBJ2=new Object();
public void obj1First() {
synchronized(OBJ1) {
printInfo("Hold OBJ1");
synchronized(OBJ2) {
printInfo("Hole OBJ2");
}
printInfo("Release OBJ2");
}
printInfo("Release OBJ1");
}
}
static class Deadlock2 {
private final static Object OBJ1=new Object();
private final static Object OBJ2=new Object();
public void obj2First() {
synchronized(OBJ2) {
printInfo("Hold OBJ2");
synchronized(OBJ1) {
printInfo("Hole OBJ1");
}
printInfo("Release OBJ1");
}
printInfo("Release OBJ2");
}
}
public static void printInfo(String info) {
System.out.println(Thread.currentThread().getName()+" "+info);
}
public static void main(String args[]) {
final Deadlock1 d1=new Deadlock1();
final Deadlock2 d2=new Deadlock2();
Thread t1=new Thread(new Runnable() {
public void run() {
for(int i=0;i<loop;i++)>
d1.obj1First();
}
Deadlocker.printInfo("Terminated");
}
}, "OBJ1_First");
Thread t2=new Thread(new Runnable() {
public void run() {
for(int i=0;i<loop;i++)>
d2.obj2First();
}
Deadlocker.printInfo("Terminated");
}
}, "OBJ2_First");
t1.start();
t2.start();
}
}
Friday, 8. August 2008
The @Override annotation added in Java5 is very useful. Recently I found out the annotation of Java6 differs from that of Java5. Java6 allows annotating a method that implements a method declared in interface with @Override whereas Java5 doesn’t allow it.
Unfortunately I couldn’t find any document on the change from java.sun.com site. Missing this issue from the release note of Java6 seems to be a mistake as http://blogs.sun.com/ahe/entry/override_snafu says.